我正试图制作一个非常简单的射击游戏,船可以向左或向右移动并发射子弹。我已经走到这一步,并意识到我可能已经搞砸了我对象和类型的位置。船和按钮当前是RelativeLayout中的ImageView。 明星背景是我的SurfaceView中唯一的东西。它实际上不是“背景”,而是随机生成的位图,使其看起来移动。
我需要创建更多的对象:子弹和敌人。主要问题是子弹需要进入船舶坐标,因此它似乎从船上发射。
我是不是错了?我应该将按钮作为位图绘制到SurfaceView上吗?我想知道最好的方法。
在当前状态下,船只从左向右无缝移动,按钮切换颜色并使声音播放。
以下是我的两个课程:
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import java.util.Random;
public class MainActivity extends Activity {
GameView gameView;
FrameLayout game;
RelativeLayout widgets;
ImageButton leftButton;
ImageButton rightButton;
ImageButton leftFireButton;
ImageButton rightFireButton;
ImageView ship;
float shipX;
MediaPlayer mp;
static final int leftButtonID = 1;
static final int rightButtonID = 2;
static final int leftFireButtonID = 3;
static final int rightFireButtonID = 4;
static final int laserId = 5;
SoundPool soundPool;
int soundID;
//Bitmap laser;
//ImageView laser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ship = new ImageView(this);
gameView = new GameView(this);
game = new FrameLayout(this);
widgets = new RelativeLayout(this);
leftButton = new ImageButton(this);
rightButton = new ImageButton(this);
leftFireButton = new ImageButton(this);
rightFireButton = new ImageButton(this);
//laser = BitmapFactory.decodeResource(getResources(), R.drawable.laser_beam);
//laser = new ImageView(this);
leftButton.setId(leftButtonID);
rightButton.setId(rightButtonID);
leftFireButton.setId(leftFireButtonID);
rightFireButton.setId(rightFireButtonID);
//laser.setId(laserId);
//ship = BitmapFactory.decodeResource(getResources(),R.drawable.spaceship_1_80x70); //should this be an image or bitmap?
//laser.setImageResource(R.drawable.laser_beam); Should be a bitmap instead?
leftButton.setImageResource(R.drawable.left_arrow);
rightButton.setImageResource(R.drawable.right_arrow);
leftFireButton.setImageResource(R.drawable.red_button);
rightFireButton.setImageResource(R.drawable.red_button);
ship.setImageResource(R.drawable.spaceship_1_80x70);
//add views to screen
game.addView(gameView);
game.addView(widgets);
widgets.addView(leftButton);
widgets.addView(rightButton);
widgets.addView(leftFireButton);
widgets.addView(rightFireButton);
widgets.addView(ship);
leftButton.setBackgroundColor(Color.TRANSPARENT);
rightButton.setBackgroundColor(Color.TRANSPARENT);
leftFireButton.setBackgroundColor(Color.TRANSPARENT);
rightFireButton.setBackgroundColor(Color.TRANSPARENT);
mp = MediaPlayer.create(this, R.raw.bass_loop);
mp.setLooping(true);
mp.start();
loadSounds(this);
leftButton.setOnTouchListener(new View.OnTouchListener() {
private Handler handler;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if(handler != null) return true;
handler = new Handler();
handler.postDelayed(action,50);
break;
case MotionEvent.ACTION_UP:
if(handler == null) return true;
handler.removeCallbacks(action);
handler = null;
break;
}
return true;
}
Runnable action = new Runnable() {
@Override public void run() {
shipX = ship.getX() - 25;
ship.setX(shipX);
handler.postDelayed(this,50);
}
};
});
rightButton.setOnTouchListener(new View.OnTouchListener() {
private Handler handler;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if(handler != null) return true;
handler = new Handler();
handler.postDelayed(action,50);
break;
case MotionEvent.ACTION_UP:
if(handler == null) return true;
handler.removeCallbacks(action);
handler = null;
break;
}
return true;
}
Runnable action = new Runnable() {
@Override public void run() {
shipX = ship.getX() + 25;
ship.setX(shipX);
handler.postDelayed(this,50);
}
};
});
leftFireButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
//TODO FIRE BULLET....
leftFireButton.setBackgroundResource(R.drawable.red_button_pressed);
soundPool.play(soundID,1.0f,0.5f,1,0,1.0f);
return true;
case MotionEvent.ACTION_UP:
leftFireButton.setBackgroundResource(R.drawable.red_button);
//widgets.removeView(laser);
return true;
}
return false;
}
});
rightFireButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
//TODO FIRE BULLET
rightFireButton.setBackgroundResource(R.drawable.red_button_pressed);
soundPool.play(soundID,1.0f,0.5f,1,0,1.0f);
return true;
case MotionEvent.ACTION_UP:
rightFireButton.setBackgroundResource(R.drawable.red_button);
//widgets.removeView(laser);
return true;
}
return false;
}
});
//Setup ship
RelativeLayout.LayoutParams shipParams = new RelativeLayout.LayoutParams(250, 250);
//Setup a 200 x 200 ImageView for Left Button
RelativeLayout.LayoutParams leftBtn = new RelativeLayout.LayoutParams(200,200);
//Setup a 200 x 200 ImageView for Right Button
RelativeLayout.LayoutParams rightBtn = new RelativeLayout.LayoutParams(200,200);
//Setup a 200 x 200 ImageView for Left Fire Button
RelativeLayout.LayoutParams leftFireBtn = new RelativeLayout.LayoutParams(200,200);
//Setup a 200 x 200 ImageView for Right Fire Button
RelativeLayout.LayoutParams rightFireBtn = new RelativeLayout.LayoutParams(200,200);
//Add rules to align the left button programmatically
leftBtn.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
leftBtn.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
//Add rules to align the right button programmatically
rightBtn.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
rightBtn.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
//Add rules to align left and right fire buttons
leftFireBtn.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
rightFireBtn.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
leftFireBtn.addRule(RelativeLayout.ABOVE,leftButton.getId());
rightFireBtn.addRule(RelativeLayout.ABOVE, rightButton.getId());
//leftFireBtn.topMargin = 850;
//rightFireBtn.topMargin = 850;
shipParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
shipParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
//shipParams.bottomMargin = 100;
//Now set the params
leftButton.setLayoutParams(leftBtn);
rightButton.setLayoutParams(rightBtn);
leftFireButton.setLayoutParams(leftFireBtn);
rightFireButton.setLayoutParams(rightFireBtn);
ship.setLayoutParams(shipParams);
//Set the content view of the game
this.setContentView(game);
}
public void loadSounds(Context context) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
soundPool = new SoundPool.Builder().setMaxStreams(10).build();
}
else {
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
}
soundID = soundPool.load(context,R.raw.laser,1);
}
@Override
protected void onPause() {
super.onPause();
mp.pause();
gameView.pause();
}
@Override
protected void onResume() {
super.onResume();
mp.start();
gameView.resume();
}
public class GameView extends SurfaceView implements Runnable {
Thread gameViewThread = null;
SurfaceHolder surfaceHolder;
boolean okToRun = true;
Bitmap star;
Bitmap three_pixel_star;
public GameView(Context context) {
super(context);
//initialize holder
surfaceHolder = this.getHolder();
}
@Override
public void run() {
while(okToRun) {
if(!surfaceHolder.getSurface().isValid()) {
continue;
}
Canvas gameCanvas = surfaceHolder.lockCanvas();
customOnDraw(gameCanvas);
surfaceHolder.unlockCanvasAndPost(gameCanvas);
}
}
protected void customOnDraw(Canvas canvas) {
Random random = new Random();
Random random1 = new Random();
canvas.drawColor(Color.BLACK);
star = BitmapFactory.decodeResource(getResources(), R.drawable.single_pixel_star);
three_pixel_star = BitmapFactory.decodeResource(getResources(),R.drawable.three_pixel_star);
canvas.drawBitmap(star, random1.nextInt(canvas.getWidth()-star.getWidth()),random1.nextInt(canvas.getHeight()-star.getHeight()), null);
canvas.drawBitmap(three_pixel_star, random.nextInt(canvas.getWidth()-three_pixel_star.getWidth()),random.nextInt(canvas.getHeight()-three_pixel_star.getHeight()), null);
}
public void pause() {
okToRun = false;
while(true) {
try {
gameViewThread.join();
} catch(InterruptedException e) {
Log.v("ERROR", e.getMessage());
}
break;
}
gameViewThread = null;
}
public void resume() {
okToRun = true;
gameViewThread = new Thread(this);
gameViewThread.start();
}
}
}
答案 0 :(得分:0)
好吧,我不知道这是否是“正确”的方式本身,但我现在有激光从我的船上射击。我制作了一个Bullet和BulletController类,并在我的onTouchListener中实现了一个方法。
Bullet类:
public class Bullet {
private float x;
private float y;
private Paint paint;
Bitmap bullet;
public Bullet(float x, float y, Context context) {
this.x = x;
this.y = y;
bullet = BitmapFactory.decodeResource(context.getResources(),R.drawable.laser_beam);
}
public void tick() {
y -= 30;
}
public void render(Canvas canvas) {
canvas.drawBitmap(bullet, x, y,null);
}
}
BulletController类:
public class BulletController {
private LinkedList<Bullet> b = new LinkedList<>();
Bullet tempBullet;
Context context;
//ImageView ship;
float x;
float y;
public BulletController(Context context) {
this.context = context;
this.x = x;
this.y = y;
addBullet(new Bullet(x, y, context));
}
public void tick() {
for(int i = 0; i < b.size(); i++) {
tempBullet = b.get(i);
tempBullet.tick();
}
}
public void render(Canvas canvas) {
for(int i = 0; i < b.size(); i++) {
tempBullet = b.get(i);
tempBullet.render(canvas);
}
}
public void addBullet(Bullet bullet) {
b.add(bullet);
}
public void removeBullet(Bullet bullet) {
b.remove(bullet);
}
}
在我的setOnTouchListener中,有两个开火按钮:
leftFireButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
//TODO FIRE BULLET....
bulletController.addBullet(new Bullet((ship.getX() + ship.getWidth()/2) - 15, ship.getY() + ship.getHeight()/2, getApplicationContext())); //<--NEW CODE
leftFireButton.setBackgroundResource(R.drawable.red_button_pressed);
soundPool.play(soundID,1.0f,0.5f,1,0,1.0f);
return true;
case MotionEvent.ACTION_UP:
leftFireButton.setBackgroundResource(R.drawable.red_button);
//widgets.removeView(laser);
return true;
}
return false;
}
});
rightFireButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
//TODO FIRE BULLET
bulletController.addBullet(new Bullet((ship.getX() + ship.getWidth()/2) - 15, ship.getY() + ship.getHeight()/2, getApplicationContext())); //<--- NEW CODE
rightFireButton.setBackgroundResource(R.drawable.red_button_pressed);
soundPool.play(soundID,1.0f,0.5f,1,0,1.0f);
return true;
case MotionEvent.ACTION_UP:
rightFireButton.setBackgroundResource(R.drawable.red_button);
//widgets.removeView(laser);
return true;
}
return false;
}
});
按下每个按钮,这是最终结果。激光器!