我编写了一个受 Space Invaders 和 Moon Patrol 启发的迷你 Android 游戏场景.可以水平射击外星人(见上文)。
也可以垂直射击外星人(见下文)。
但是添加外星人不会“缩放”,例如添加 15 个外星人在所有可能的碰撞中移动将是非常困难的。原来的太空入侵者和月球巡逻队解决了这个问题,是否可以制定与我正在使用的策略不同的策略?外星人的确切移动并不重要,重要的是它“有趣”。
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v4.view.MotionEventCompat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.ArrayList;
import java.util.List;
public class ParallaxView extends SurfaceView implements Runnable {
List<Background> backgrounds;
private volatile boolean running;
private Thread gameThread = null;
// For drawing
private Paint paint;
private Canvas canvas;
private SurfaceHolder ourHolder;
// Holds a reference to the Activity
Context context;
// Control the fps
long fps = 60;
// Screen resolution
int screenWidth;
int screenHeight;
private void update() {
// Update all the background positions
for (Background bg : backgrounds) {
bg.update(fps);
}
}
ParallaxView(Context context, int screenWidth, int screenHeight) {
super(context);
this.context = context;
this.screenWidth = screenWidth;
this.screenHeight = screenHeight;
// Initialize our drawing objects
ourHolder = getHolder();
paint = new Paint();
// Initialize our array list
backgrounds = new ArrayList<>();
//load the background data into the Background objects and
// place them in our GameObject arraylist
backgrounds.add(new Background(
this.context,
screenWidth,
screenHeight,
"bg", 0, 120, 50));
backgrounds.add(new Background(
this.context,
screenWidth,
screenHeight,
"grass", 70, 110, 200));
// Add more backgrounds here
}
@Override
public void run() {
while (running) {
long startFrameTime = System.currentTimeMillis();
update();
if (j > 2000) {
j = -50;
k = 0;
}
if (o > 2000) {
o = -50;
l = 0;
}
draw();
// Calculate the fps this frame
long timeThisFrame = System.currentTimeMillis() - startFrameTime;
if (timeThisFrame >= 1) {
fps = 1000 / timeThisFrame;
}
}
}
int numberOfshots = 1;
int[] i = new int[200];
int j = 0;
int k = 0;
int l = 0;
int m = 0;
int o = 0;
boolean down = true;
long lastTurn = System.currentTimeMillis();
int xbuggy = 0;
int xbuggy2 = 0;
boolean down2 = true;
long lastTurn2 = System.currentTimeMillis();
long lastTurn3 = System.currentTimeMillis();
boolean jump = false;
boolean shoot = false;
int ind = 0;
private void draw() {
if (ourHolder.getSurface().isValid()) {
//First we lock the area of memory we will be drawing to
canvas = ourHolder.lockCanvas();
if (jump) {
xbuggy = xbuggy + 4;
}
if (shoot) {
xbuggy2 = xbuggy2 + 4;
}
if (System.currentTimeMillis() - lastTurn3 >= 1000) {
// Change direction here
jump = false;
lastTurn3 = System.currentTimeMillis();
xbuggy = 0;
}
//draw a background color
canvas.drawColor(Color.argb(255, 0, 0, 0));
// Draw the background parallax
drawBackground(0);
// Draw the rest of the game
paint.setTextSize(60);
paint.setColor(Color.argb(255, 255, 255, 255));
//canvas.drawText("MOONPATROL3000", 350, screenHeight / 100 * 5, paint);
int resID = context.getResources().getIdentifier("vehicle",
"drawable", context.getPackageName());
int alienResID = context.getResources().getIdentifier("object3_hdpi",
"drawable", context.getPackageName());
int alienResID2 = context.getResources().getIdentifier("object2_hdpi",
"drawable", context.getPackageName());
int alienResID3 = context.getResources().getIdentifier("object1_hdpi",
"drawable", context.getPackageName());
// Load the bitmap using the id
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resID);
Bitmap alienbitmap = BitmapFactory.decodeResource(context.getResources(), alienResID);
Bitmap alienbitmap2 = BitmapFactory.decodeResource(context.getResources(), alienResID2);
Bitmap alienbitmap3 = BitmapFactory.decodeResource(context.getResources(), alienResID3);
//paint.setTextSize(220);
for (int i1 = 0; i1 < numberOfshots; i1++) {
// if horizontal missile hits alien 0
if (java.lang.Math.abs(j - i[i1]) * 2 < (alienbitmap.getWidth() + 60) && java.lang.Math.abs(k +150+ screenHeight / 100 * 45 - (float) (screenHeight * 0.61)) * 2 < (alienbitmap.getHeight() + 60)) {
//y1[i2] = -random.nextInt(1000); // reset to new vertical position
//score += 1;
//onScoreListener.onScore(score);
Log.d("missile", "missile hit! ");
j=-200;
}
// if vertical missile hits alien 0
if (java.lang.Math.abs(j - 185) * 2 < (alienbitmap.getWidth() + 60) && java.lang.Math.abs(j + 150 + screenHeight / 100 * 45 - (screenHeight / 100 * 95 - i[i1] - xbuggy2)) * 2 < (alienbitmap.getHeight() + 60)) {
//y1[i2] = -random.nextInt(1000); // reset to new vertical position
//score += 1;
//onScoreListener.onScore(score);
Log.d("missile", "missile hit! ");
j=-200;
}
// if horizontal missile hits alien 1, right now this won't happen
if (java.lang.Math.abs(j - i[i1]) * 2 < (alienbitmap.getWidth() + 60) && java.lang.Math.abs(k +150+ screenHeight / 100 * 45 - (float) (screenHeight * 0.61)) * 2 < (alienbitmap.getHeight() + 60)) {
//y1[i2] = -random.nextInt(1000); // reset to new vertical position
//score += 1;
//onScoreListener.onScore(score);
Log.d("missile", "missile hit! ");
j=-200;
}
// if vertical missile hits alien 1
if (java.lang.Math.abs(o + 10 - 185) * 2 < (alienbitmap.getWidth() + 60) && java.lang.Math.abs(l + screenHeight / 100 * 25 - (screenHeight / 100 * 95 - i[i1] - xbuggy2)) * 2 < (alienbitmap.getHeight() + 60)) {
//y1[i2] = -random.nextInt(1000); // reset to new vertical position
//score += 1;
//onScoreListener.onScore(score);
Log.d("missile", "missile hit! ");
o=-200;
}
canvas.drawText("o", i[i1], (float) (screenHeight * 0.61), paint);
canvas.drawText("o", 185, screenHeight / 100 * 95 - i[i1] - xbuggy2, paint);
if (i1 == numberOfshots - 1 && i[i1] > screenWidth) {
if (numberOfshots > 0) numberOfshots--;
if (ind > 0) ind--;
}
}
if (System.currentTimeMillis() - lastTurn >= 2000) {
// Change direction here
down = !down;
lastTurn = System.currentTimeMillis();
}
if (System.currentTimeMillis() - lastTurn2 >= 7000) {
// Change direction here
down2 = !down2;
lastTurn2 = System.currentTimeMillis();
}
canvas.drawBitmap(alienbitmap, j, k +150+ screenHeight / 100 * 45, paint);
canvas.drawBitmap(alienbitmap2, o + 10, l + screenHeight / 100 * 25, paint);
//canvas.drawBitmap(alienbitmap3, j+20, k+screenHeight / 100 * 5, paint);
drawBackground(1);
canvas.drawBitmap(bitmap, 50, (float) (screenHeight * 0.5) - xbuggy, paint);
// Draw the foreground parallax
for (int n = 0; n < numberOfshots; n++)
i[n] = i[n] + 20;
j = j + 10;
o = o + 7;
if (!down)
k=k+2;
else
k=k-2;
if (!down2)
l++;
else
l--;
// Unlock and draw the scene
ourHolder.unlockCanvasAndPost(canvas);
}
}
// Clean up our thread if the game is stopped
public void pause() {
running = false;
try {
gameThread.join();
} catch (InterruptedException e) {
// Error
}
}
// Make a new thread and start it
// Execution moves to our run method
public void resume() {
running = true;
gameThread = new Thread(this);
gameThread.start();
}
private void drawBackground(int position) {
// Make a copy of the relevant background
Background bg = backgrounds.get(position);
// define what portion of images to capture and
// what coordinates of screen to draw them at
// For the regular bitmap
Rect fromRect1 = new Rect(0, 0, bg.width - bg.xClip, bg.height);
Rect toRect1 = new Rect(bg.xClip, bg.startY, bg.width, bg.endY);
// For the reversed background
Rect fromRect2 = new Rect(bg.width - bg.xClip, 0, bg.width, bg.height);
Rect toRect2 = new Rect(0, bg.startY, bg.xClip, bg.endY);
//draw the two background bitmaps
if (!bg.reversedFirst) {
canvas.drawBitmap(bg.bitmap, fromRect1, toRect1, paint);
canvas.drawBitmap(bg.bitmapReversed, fromRect2, toRect2, paint);
} else {
canvas.drawBitmap(bg.bitmap, fromRect2, toRect2, paint);
canvas.drawBitmap(bg.bitmapReversed, fromRect1, toRect1, paint);
}
}
// Because we call this from onTouchEvent, this code will be executed for both
// normal touch events and for when the system calls this using Accessibility
@Override
public boolean performClick() {
super.performClick();
launchMissile();
return true;
}
private void launchMissile() {
i[ind] = 350;
ind++;
xbuggy2 = 0;
shoot = true;
}
// event listener for when the user touches the screen
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean gameOver = false;
//if (paused) {
// paused = false;
//}
int action = MotionEventCompat.getActionMasked(event);
int coordX = (int) event.getX();
int coordY = (int) event.getY();
Log.d("coordY", "coordY " + coordY);
if (coordX < 220 && xbuggy == 0 && action == MotionEvent.ACTION_MOVE) {
jump = true;
shoot = false;
lastTurn3 = System.currentTimeMillis();
return true; // do nothing
}
if (coordX > 219 && action == MotionEvent.ACTION_DOWN) {
numberOfshots++;
performClick();
return true;
}
return true;
}
}
更新
我已经开始根据以下内容为外星人封装逻辑。
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class Alien {
public Alien(){}
public Alien(Context context, String name) {
setAlienResID(context.getResources().getIdentifier("object3_hdpi",
"drawable", context.getPackageName()));
setAlienbitmap(BitmapFactory.decodeResource(context.getResources(), this.getAlienResID()));
}
public int getAlienResID() {
return alienResID;
}
public void setAlienResID(int alienResID) {
this.alienResID = alienResID;
}
public Bitmap getAlienbitmap() {
return alienbitmap;
}
public void setAlienbitmap(Bitmap alienbitmap) {
this.alienbitmap = alienbitmap;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
int alienResID;
Bitmap alienbitmap;
int width;
int height;
}
public class AttackingAlien extends Alien {
public AttackingAlien(Context context, String name) {
super(context, name);
}
}
更新 2
我已经改变了策略。现在我正在画一艘宇宙飞船,它将轰炸月球车。
相关代码是
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v4.view.MotionEventCompat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.ArrayList;
import java.util.List;
public class ParallaxView extends SurfaceView implements Runnable {
List<Background> backgrounds;
private volatile boolean running;
private Thread gameThread = null;
// For drawing
private Paint paint;
private Canvas canvas;
private SurfaceHolder ourHolder;
// Holds a reference to the Activity
Context context;
// Control the fps
long fps = 60;
// Screen resolution
int screenWidth;
int screenHeight;
private void update() {
// Update all the background positions
for (Background bg : backgrounds) {
bg.update(fps);
}
}
ParallaxView(Context context, int screenWidth, int screenHeight) {
super(context);
this.context = context;
this.screenWidth = screenWidth;
this.screenHeight = screenHeight;
// Initialize our drawing objects
ourHolder = getHolder();
paint = new Paint();
// Initialize our array list
backgrounds = new ArrayList<>();
//load the background data into the Background objects and
// place them in our GameObject arraylist
backgrounds.add(new Background(
this.context,
screenWidth,
screenHeight,
"bg", 0, 120, 50));
backgrounds.add(new Background(
this.context,
screenWidth,
screenHeight,
"grass", 70, 110, 200));
// Add more backgrounds here
}
@Override
public void run() {
while (running) {
long startFrameTime = System.currentTimeMillis();
update();
if (j > 2000) {
j = -50;
k = 0;
}
if (o > 2000) {
o = -50;
l = 0;
}
draw();
// Calculate the fps this frame
long timeThisFrame = System.currentTimeMillis() - startFrameTime;
if (timeThisFrame >= 1) {
fps = 1000 / timeThisFrame;
}
}
}
int numberOfshots = 1;
int[] i = new int[200];
int j = 0;
int k = 0;
int l = 0;
int m = 0;
int o = 0;
boolean down = true;
long lastTurn = System.currentTimeMillis();
int xbuggy = 0;
int xbuggy2 = 0;
boolean down2 = true;
long lastTurn2 = System.currentTimeMillis();
long lastTurn3 = System.currentTimeMillis();
long lastTurn4 = System.currentTimeMillis();
boolean jump = false;
boolean shoot = false;
int ind = 0;
int numberOfAlienshots = 1;
int missileOffSetY = 0;
private void draw() {
if (ourHolder.getSurface().isValid()) {
//First we lock the area of memory we will be drawing to
canvas = ourHolder.lockCanvas();
if (jump) {
xbuggy = xbuggy + 4;
}
if (shoot) {
xbuggy2 = xbuggy2 + 4;
}
if (System.currentTimeMillis() - lastTurn4 >= 2000) {
// Change direction here
//jump = false;
lastTurn4 = System.currentTimeMillis();
missileOffSetY = 0;
}
if (System.currentTimeMillis() - lastTurn3 >= 1000) {
// Change direction here
jump = false;
lastTurn3 = System.currentTimeMillis();
xbuggy = 0;
}
//draw a background color
canvas.drawColor(Color.argb(255, 0, 0, 0));
// Draw the background parallax
drawBackground(0);
// Draw the rest of the game
paint.setTextSize(60);
paint.setColor(Color.argb(255, 255, 255, 255));
//canvas.drawText("MOONPATROL3000", 350, screenHeight / 100 * 5, paint);
int resID = context.getResources().getIdentifier("vehicle",
"drawable", context.getPackageName());
Alien alien1 = new AttackingAlien(context, "right_side_hdpi");
Alien alien2 = new AttackingAlien(context, "object2_hdpi");
Alien alien3 = new AttackingAlien(context, "object1_hdpi");
int alienResID = context.getResources().getIdentifier("right_side_hdpi",
"drawable", context.getPackageName());
int alienResID2 = context.getResources().getIdentifier("right_side_hdpi",
"drawable", context.getPackageName());
int alienResID3 = context.getResources().getIdentifier("right_side_hdpi",
"drawable", context.getPackageName());
// Load the bitmap using the id
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resID);
Bitmap alienbitmap = BitmapFactory.decodeResource(context.getResources(), alienResID);
Bitmap alienbitmap2 = BitmapFactory.decodeResource(context.getResources(), alienResID2);
Bitmap alienbitmap3 = BitmapFactory.decodeResource(context.getResources(), alienResID3);
//paint.setTextSize(220);
//for (int i1 = 0; i1 < numberOfAlienshots; i1++) {
if (missileOffSetY < 300) {
canvas.drawText("|", o + 10 + alienbitmap2.getWidth() / 2, l + screenHeight / 100 * 25 + 75 + missileOffSetY, paint);
missileOffSetY = missileOffSetY + 10;
}
for (int i1 = 0; i1 < numberOfshots; i1++) {
// if horizontal missile hits alien 0
if (java.lang.Math.abs(j - i[i1]) * 2 < (alien1.getWidth() + 60) && java.lang.Math.abs(k +150+ screenHeight / 100 * 45 - (float) (screenHeight * 0.61)) * 2 < (alien1.getHeight() + 60)) {
//y1[i2] = -random.nextInt(1000); // reset to new vertical position
//score += 1;
//onScoreListener.onScore(score);
Log.d("missile", "missile hit! ");
j=-200;
}
// if vertical missile hits alien 0
if (java.lang.Math.abs(j - 185) * 2 < (alienbitmap.getWidth() + 60) && java.lang.Math.abs(j + 150 + screenHeight / 100 * 45 - (screenHeight / 100 * 95 - i[i1] - xbuggy2)) * 2 < (alienbitmap.getHeight() + 60)) {
j=-200;
}
// if horizontal missile hits alien 1, right now this won't happen
if (java.lang.Math.abs(j - i[i1]) * 2 < (alienbitmap.getWidth() + 60) && java.lang.Math.abs(k +150+ screenHeight / 100 * 45 - (float) (screenHeight * 0.61)) * 2 < (alienbitmap.getHeight() + 60)) {
j=-200;
}
// if vertical missile hits alien 1
if (java.lang.Math.abs(o + 10 - 185) * 2 < (alienbitmap.getWidth() + 60) && java.lang.Math.abs(l + screenHeight / 100 * 25 - (screenHeight / 100 * 95 - i[i1] - xbuggy2)) * 2 < (alienbitmap.getHeight() + 60)) {
o=-200;
}
canvas.drawText("o", i[i1], (float) (screenHeight * 0.61), paint);
canvas.drawText("o", 185, screenHeight / 100 * 95 - i[i1] - xbuggy2, paint);
if (i1 == numberOfshots - 1 && i[i1] > screenWidth) {
if (numberOfshots > 0) numberOfshots--;
if (ind > 0) ind--;
}
}
if (System.currentTimeMillis() - lastTurn >= 2000) {
// Change direction here
down = !down;
lastTurn = System.currentTimeMillis();
}
if (System.currentTimeMillis() - lastTurn2 >= 7000) {
// Change direction here
down2 = !down2;
lastTurn2 = System.currentTimeMillis();
}
// canvas.drawBitmap(alien1.getAlienbitmap(), j, k +150+ screenHeight / 100 * 45, paint);
canvas.drawBitmap(alienbitmap2, o + 10, l + screenHeight / 100 * 25, paint);
//canvas.drawBitmap(alienbitmap3, j+20, k+screenHeight / 100 * 5, paint);
drawBackground(1);
canvas.drawBitmap(bitmap, 50, (float) (screenHeight * 0.5) - xbuggy, paint);
// Draw the foreground parallax
for (int n = 0; n < numberOfshots; n++)
i[n] = i[n] + 20;
j = j + 10;
o = o + 7;
if (!down)
k=k+2;
else
k=k-2;
if (!down2)
l++;
else
l--;
// Unlock and draw the scene
ourHolder.unlockCanvasAndPost(canvas);
}
}
// Clean up our thread if the game is stopped
public void pause() {
running = false;
try {
gameThread.join();
} catch (InterruptedException e) {
// Error
}
}
// Make a new thread and start it
// Execution moves to our run method
public void resume() {
running = true;
gameThread = new Thread(this);
gameThread.start();
}
private void drawBackground(int position) {
// Make a copy of the relevant background
Background bg = backgrounds.get(position);
// define what portion of images to capture and
// what coordinates of screen to draw them at
// For the regular bitmap
Rect fromRect1 = new Rect(0, 0, bg.width - bg.xClip, bg.height);
Rect toRect1 = new Rect(bg.xClip, bg.startY, bg.width, bg.endY);
// For the reversed background
Rect fromRect2 = new Rect(bg.width - bg.xClip, 0, bg.width, bg.height);
Rect toRect2 = new Rect(0, bg.startY, bg.xClip, bg.endY);
//draw the two background bitmaps
if (!bg.reversedFirst) {
canvas.drawBitmap(bg.bitmap, fromRect1, toRect1, paint);
canvas.drawBitmap(bg.bitmapReversed, fromRect2, toRect2, paint);
} else {
canvas.drawBitmap(bg.bitmap, fromRect2, toRect2, paint);
canvas.drawBitmap(bg.bitmapReversed, fromRect1, toRect1, paint);
}
}
// Because we call this from onTouchEvent, this code will be executed for both
// normal touch events and for when the system calls this using Accessibility
@Override
public boolean performClick() {
super.performClick();
launchMissile();
return true;
}
private void launchMissile() {
i[ind] = 350; // what does it do?
ind++;
xbuggy2 = 0;
shoot = true;
}
// event listener for when the user touches the screen
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean gameOver = false;
//if (paused) {
// paused = false;
//}
int action = MotionEventCompat.getActionMasked(event);
int coordX = (int) event.getX();
int coordY = (int) event.getY();
Log.d("coordY", "coordY " + coordY);
if (coordX < 220 && xbuggy == 0 && action == MotionEvent.ACTION_MOVE) {
jump = true;
shoot = false;
lastTurn3 = System.currentTimeMillis();
return true; // do nothing
}
if (coordX > 219 && action == MotionEvent.ACTION_DOWN) {
numberOfshots++;
performClick();
return true;
}
return true;
}
}
最佳答案
您最大的错误似乎是在绘制例程中分配了 4 个位图。在 onCreate 中分配这些位图并简单地调用全局位图,您初始化了 onCreate()。那将解决您的问题。您可以在它们的位置绘制它们。
private void draw() {
Alien alien1 = new AttackingAlien(context, "right_side_hdpi");
Alien alien2 = new AttackingAlien(context, "object2_hdpi");
Alien alien3 = new AttackingAlien(context, "object1_hdpi");
您分配了一堆内存对象来调用上下文并扩展可绘制对象和一堆其他工作。你本可以使用上一次滴答时相同的外星人。
int alienResID = context.getResources().getIdentifier("right_side_hdpi",
"drawable", context.getPackageName());
int alienResID2 = context.getResources().getIdentifier("right_side_hdpi",
"drawable", context.getPackageName());
int alienResID3 = context.getResources().getIdentifier("right_side_hdpi",
"drawable", context.getPackageName());
外星人 ID 与上一个刻度没有变化。
// Load the bitmap using the id
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resID);
Bitmap alienbitmap = BitmapFactory.decodeResource(context.getResources(), alienResID);
Bitmap alienbitmap2 = BitmapFactory.decodeResource(context.getResources(), alienResID2);
Bitmap alienbitmap3 = BitmapFactory.decodeResource(context.getResources(), alienResID3);
这些是上次滴答的相同位图,位图很大,从资源中获取它们很慢,你每次都在做这个。
}
}
大多数其他东西会在这里和那里减少半毫秒,但这里可能会让你达到正确的 FPS 球场。
即使你有其他人也不要担心。
您的大部分问题都可以通过加快例程来解决。现在是说的好时机,你做错了。执行此操作的典型且正确的方法是每 17 毫秒左右循环一次。其余时间暂停。有些错误很明显。
您最大的错误似乎是在绘制例程中分配了 4 个位图。
但是,绘制例程只绘制。您在 Canvas 上绘制需要发生的事情,就是这样。你不分配任何东西你不膨胀任何东西,你把你拥有的数字放在东西所在的位置,然后在那个位置绘制你已经加载到内存中的东西。
在绘制例程中,您正在滴答作响并进行碰撞检测,并为此分配一堆对象,无论如何都必须在一瞬间将它们扔进木片机中。
您不应在初始化之外创建任何对象,或者在存在新外星人时的那些特殊情况下创建任何对象。您不应该在绘图程序中的任何地方使用"new"。曾经。
您正在使用蛮力进行碰撞检测,最终不要。找到一个你喜欢的不错的加速结构并使用它。对于 1 个对象,这无关紧要。
不要调用一些外星人类,虽然它看起来更漂亮,但您需要外星人边界框的原始数字。然后,您希望将它们保留在某种结构中,以便可以非常快速地引用它们(您需要在不到 17 毫秒的时间内获得框架)。调用一堆宽度命令并没有那么有用,即使它们改变了大小,也只是改变了命中框的数字。这些方法允许你为数据提供一些很好的结构,比如有一个排序的命中框数组,你可以对它们进行二分搜索,并通过 log(n) 更新结构来查找移动的对象是否在 log(n) 时间内击中对象,或者遍历Axis Aligned Bound Box Tree的各种方法。这是您最终需要的东西,但只要您保持简单,它可能会在没有这个的情况下工作。不过,说实话,这只是你的位图在做大部分减速。
还有很多其他基本问题,例如将边界框放在 if 语句中而不是制作两个额外的矩形。但是还有其他问题,比如制作矩形!您使用实际位置调用绘图,而不是分配一大堆对象来调用函数。只需调用带有数字的函数即可。
你应该有一个例程,根据这些东西的位置为你画图。它应该能够在不到 17 毫秒的时间内绘制出它需要绘制的所有内容。如果不能,您将永远无法达到您需要达到的 60fps。所以在这种情况下,画更少的东西并做得更好。那个空间背景需要是位图吗?你能不能为天空画一堆点,然后相应地调整图形。你的绘图程序从不分配任何东西。时期。如果你需要分配一些东西,它应该在 init 期间进行。分配是你存在的祸根。
你的触摸会更新东西的位置。 AI/Physics 标记还会更新事物的位置并检查是否存在共谋。 draw 只根据内存中的位置和东西绘制东西。
在它自己的线程中运行更新位置刻度。您只需要处理读取和写入相同数据的并发位。它只需要同步绘制数据的变化数据读取,因此将这些部分(触摸中的位置更新,tick 中的位置更新,以及获取绘制例程本身的位置)扔到具有相同对象的同步块(synchronized block)中。
关于java - 改善太空外星人的移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50615850/