package com.qianfeng.view;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
public class Gold {
int x;
int y;
int width = 40;
int height = 40;
Image goldImg = null;
int speed = 2;
int newGoldTime = 5;
int goldPrice = 10;
int imageName;
public void init() {
// 21 - 26
imageName = new Random().nextInt(6) + 21;
x = GameView.GameViewWidth - width;
y = new Random().nextInt(390);
try {
goldImg = ImageIO.read(new File("image/" + imageName + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void goldPaint(Graphics graphics) {
graphics.drawImage(goldImg, x, y, width, height, null);
}
//金币的移动函数
public void step() {
x = x - speed;
}
}
效果:
----------------------
碰撞算法
判断两个矩形的x轴和y轴是否都相交
// 碰撞算法的实现
if (person.x + person.width > gold2.x
&& person.x < gold2.width + gold2.x
&& person.y + person.height > gold2.y
&& person.y < gold2.y + gold2.height) {
goldIterator.remove();
}
效果:(把碰到的金币都吃掉)
----------------------
吃金币:类似
package com.qianfeng.view;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class GameMainPanel extends JPanel implements KeyListener {
Image backGroundImage = null;
Image scoreImage = null;
Person person = new Person();
// 实例化一个金币集合
java.util.List<Gold> goldList = new LinkedList<Gold>();
// 实例化一个炸弹集合
java.util.List<Bomb> bombList = new LinkedList<Bomb>();
public void init() {
// 初始person
person.init();
try {
scoreImage = ImageIO.read(new File("image/a12.png"));
backGroundImage = ImageIO.read(new File("image/cc.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
// 背景图移动的介质
int backindex = 0;
// 金币移动的介质
int goldindex = 0;
// 炸弹移动的介质
int bombindex = 0;
// paint这个函数在一个线程中每隔10ms就会加载一次
@Override
public void paint(Graphics g) {
System.out.println("场景移动" + backindex);
// 所以这个paint里面的所有代码都是10ms就会加载一次
g.drawImage(backGroundImage, backindex--, 0, GameView.GameViewWidth,
GameView.GameViewHeight,null);
// 在窗体的最右边添加一个同等大小的图层
// 以同等的速度向左移动
g.drawImage(backGroundImage, GameView.GameViewWidth + backindex, 0, GameView.GameViewWidth,
GameView.GameViewHeight,null);
// 第一个图层完全移出窗体的时候
if (backindex == -GameView.GameViewWidth) {
// 让两张图片归位
backindex = 0;
}
g.drawImage(scoreImage, 80, 40, 259, 64, null);
// 设置画笔颜色
g.setColor(Color.orange);
// 设置画笔字体
g.setFont(new Font("微软雅黑", Font.BOLD,15));
// 使用画笔来写字
g.drawString("王小姗的当前分数: "+ backindex + " 分", 120, 80);
// 渲染person
person.personPaint(g);
// 其他绘制代码。。。
person.low();//更新person位置
Gold gold = new Gold();
if(goldindex++ % gold.newGoldTime ==0){
gold.init();
goldList.add(gold);
}
for (Gold gold2 : goldList) {
// 调用金币的移动函数
gold2.step();
gold2.goldPaint(g);
}
Iterator<Gold> goldIterator = goldList.iterator();
while (goldIterator.hasNext()) {
Gold gold2 = (Gold) goldIterator.next();
// 碰撞算法的实现
if (person.x + person.width > gold2.x
&& person.x < gold2.width + gold2.x
&& person.y + person.height > gold2.y
&& person.y < gold2.y + gold2.height) {
goldIterator.remove();
}
if (gold2.x <= -gold2.width) {
System.out.print("删除金币"+gold2);
goldIterator.remove();
}
}
Bomb bomb = new Bomb();
if(bombindex++ % bomb.bombTime ==0){
bombList.add(bomb);
}
for (Bomb bomb2 : bombList) {
// 调用炸彈的移动函数
bomb2.step();
bomb2.bombPaint(g);
}
Iterator<Bomb> bombIterator = bombList.iterator();
while (bombIterator.hasNext()) {
Bomb bomb2 = (Bomb) bombIterator.next();
// 碰撞算法的实现
if (person.x + person.width > bomb2.x
&& person.x < bomb2.width + bomb2.x
&& person.y + person.height > bomb2.y
&& person.y < bomb2.y + bomb2.height) {
bombIterator.remove();
}
if (bomb2.x <= -bomb2.width) {
System.out.print("删除炸弹"+bomb2);
bombIterator.remove();
}
}
}
// 此游戏是10ms1帧的游戏
// 帧数就是游戏画面渲染一次所需要的时间
public void action() {
// 创建一个线程
Thread thread = new Thread(){
@Override
// run函数就是线程函数
public void run() {
// 死循环
while(true) {
// 线程暂停10ms
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO: handle exception
}
// 再次刷新图层
// repaint()函数等同于再次执行@Override
// public void paint(Graphics g) {
//
// }
//
repaint();
}
}
};
thread.start();
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
// 键盘按下事件
@Override
public void keyPressed(KeyEvent e) {
System.out.print("aaaaaa");
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
person.x = person.x +40;
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
person.y = person.y -40;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
person.x = person.x -40;
}
}
// 键盘抬起事件
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
package com.qianfeng.view;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
public class Bomb {
int x;
int y;
int width;
int height;
Image boomImage;
int speed;
int bombTime;
public Bomb() {
x = GameView.GameViewWidth;
y = new Random().nextInt(420);
width = 100;
height = 100;
speed = 3;
bombTime = 130;
try {
boomImage = ImageIO.read(new File("image/daodan.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void bombPaint(Graphics graphics) {
graphics.drawImage(boomImage, x, y, width, height, null);
}
// 炸弹的移动函数
public void step() {
x = x - speed;
}
}
效果:(可以吃掉炸弹)
金币和炸弹的代码有处不同:
gold类里public void init() {}和bomb类里public Bomb() {}
public void init() {}
是一个普通的实例方法,它可以在类中定义并由对象进行调用。这个方法可以用来初始化对象的状态、设置初始值或执行其他初始化操作。在你的代码中,init()
方法被用于初始化金币和炸弹对象的位置、图像等属性。
public Bomb() {}
是一个构造方法(Constructor),它用于创建对象时被调用。构造方法在使用 new
关键字创建对象时自动调用,用于执行对象的初始化操作。在你的代码中,Bomb
类的构造方法被用于创建炸弹对象并设置炸弹的初始属性。
区别:
init()
方法是自定义的实例方法,需要手动调用,可以在对象创建后的任意时刻调用。- 构造方法是特殊的方法,用于创建对象时自动调用,不需要手动调用。
在你的代码中,Bomb
类的构造方法被用于创建炸弹对象,而不需要额外调用 init()
方法。构造方法会在对象创建时自动执行初始化操作。