java实现熊猫闯关小游戏
游戏规则:熊猫在冰雪世界向前走。遇见怪兽时鼠标点击左键跳跃,若成功避开怪兽,则游戏继续,若与怪兽相撞,则游戏结束。
下面贴出实现效果图:
游戏开始后效果:
下面介绍实现思路:
首先需要图片素材。熊猫的走动,狼和怪兽,鸟的走动都是以多副图片不断循环播放实现的。
用两张连续的背景图片依次向左移动实现背景图片的移动,如果运行程序的话,可以发现,其实熊猫原地不动,即熊猫相对于窗口的位置并不改变,是通过背景图片左移来实现熊猫向前走的效果的。假设窗口宽是1280像素,那么第一张背景图片左边界从窗口0像素起,第二张背景图片从1280像素位置起,同时向左移动,而此时熊猫只要原位置不断循环图片就可以了。
狼和怪兽是相对于窗口移动的,运行游戏同样可以发现,狼从窗口右侧出现,从左侧消失,就能看出狼是确实移动的。怎么实现不断有狼跑向熊猫呢?通过改变狼的位置。狼从右侧窗口出现到从左侧窗口消失时,其实并没有“消失”,它只是改变了位置,又重新回到了起点,然后重新从窗口右侧跑向左侧。
考虑到个人美工能力。这里贴出实现熊猫等动物动作的连续图片。注意图片顺序。
下面给出游戏结构图解:
下面分别给出代码:
鸟:
package day02;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Bird {
int x;
int y;
Image[] bird;
public Bird(){
x=1280;
y=50;
bird=new Image[3];
for(int i=0;i<bird.length;i++){
bird[i]=new ImageIcon("Images02/enemy4-sheet"+i+".png").getImage();
}
}
}
Gold(金币):
package day02;
import java.awt.Image;
import java.util.Random;
import javax.swing.ImageIcon;
public class Gold {
int x;
int y;
int width;
int height;
Image gold;
Random r;
public Gold(){ //金币
width=34;
height=34;
r=new Random();
x=r.nextInt(1280);
y=300;
gold=new ImageIcon("Images02/coin-sheet0.png").getImage();
}
public void move(){
x=x-3;
if(x<-17){
x=1280;
}
}
public boolean score(Pander pander){//得分 如何得到熊猫移动的y?
if(pander.y+pander.height>300&&pander.y+pander.height<334){
//if(pander.y>500){
if(pander.x+pander.width>x&&pander.x<x+width){
return true;
}
}
return false;
}
}
Monster:
package day02;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Monster {
int x;
int y;
int j;
int width;
Image[] monster;
public Monster(){
x=2500;
y=520;
width=180;
monster=new Image[8];
for(int i=0;i<monster.length;i++){
monster[i]=new ImageIcon("Images02/怪兽"+(i+1)+".png").getImage();
}
}
public void move(){
x=x-10;//改变速度
if(x<-130){
x=2500; //狼的是从1500处开始 , 与狼的位置时间错开
}
}
//定义判断碰撞方法
public boolean hit(Pander pander){
if(pander.y+pander.height>y){
if(pander.x+pander.width>x&&pander.x<x+width){
return true;
}
}
return false;
}
}
Mypanel:
package day02;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class MyPanel extends JPanel { // extends 继承
// 自己创建的Mypanel类继承了系统中JPanel的功能,可更改其中的功能
Snow[] xueHua;
Image blackGround;
Pander pander;
Wolf lang; // 狼
Monster guaiShou; // 怪兽
Bird niao; // 鸟
Sign sg;
Gold[] jinBi;
Image startimg;
Image overimg;
// 游戏状态
int state = 0;
public static final int START = 0;
public static final int RUNNING = 1;
public static final int GAMEOVER = 2;
public MyPanel() {
startimg = new ImageIcon("Images02/btnplay-sheet0.png").getImage(); // 开始按钮图片赋给startimg
overimg = new ImageIcon("Images02/btnrestart-sheet0.png").getImage();// 循环按钮赋给overimg
blackGround = new ImageIcon("Images02/背景.jpg").getImage();// 底层背景
pander = new Pander();
lang = new Wolf(); // 狼
guaiShou = new Monster();
niao = new Bird();
sg = new Sign(); // 上层图片背景
jinBi = new Gold[5];
{
for (int i = 0; i < 5; i++) {
jinBi[i] = new Gold();
}
}
xueHua = new Snow[30];// for中不是已经有new了么?此处为什么还要加
for (int i = 0; i < 30; i++) {
xueHua[i] = new Snow();
}
} // MyPanel
int index = 0;
int x = 0;
public void paint(Graphics g) {// g为变量名 Graphics是数据类型 作为一个画图的工具
super.paint(g);// super相当于父类 用父类的画笔功能
if (x < -1280) {
x = 0;
}
g.drawImage(blackGround, x + 0, 0, null);// 画第一张背景图
g.drawImage(blackGround, x + 1280, 0, null);// 画第二张背景图
g.drawImage(lang.wolf[index % 6], lang.x, lang.y, null);
g.drawImage(niao.bird[index % 3], niao.x + x, niao.y, null);
g.drawImage(guaiShou.monster[(index / 2) % 2], guaiShou.x, guaiShou.y, null);
g.drawImage(pander.pimg[(index / 2) % 4], pander.x, pander.y, null);// 为什么放null?
// %8取余,余数范围0-7
// index/2???
for (int i = 0; i < 30; i++) { // 画雪花
g.drawImage(xueHua[i].snow, xueHua[i].x, xueHua[i].y, this);
}
for (int i = 0; i < 5; i++) { // 画金币
g.drawImage(jinBi[i].gold, jinBi[i].x, jinBi[i].y, this);
}
index++; // 实现角色图片更换
x -= 3; // 这里实现背景图片左移
switch (state) {
case START:
g.drawImage(sg.sign, sg.x, sg.y, null);
g.drawImage(startimg, 550, 525, null);
break;
case GAMEOVER:
g.drawImage(sg.sign, sg.x, sg.y, null);
g.drawImage(overimg, 550, 525, null);
break;
}
} // paint()
// 定义一个执行的方法
public void action() throws Exception { // 匿名内部类 需加;
// 创建鼠标监听器 Listener:监听器 Adapter:适配器
// 监听器需要5种全列出 适配器只需列出需要的
MouseListener l = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
switch (state) {
case START:
state = RUNNING;
break;
case RUNNING:
// 熊猫跳
if (pander.y == 570) { // 鼠标在跳起过程中不能点击
pander.jump();
}
break;
case GAMEOVER:
state = RUNNING;
pander.y = 570;
lang = new Wolf();
guaiShou = new Monster();
break;
} // switch
}// mousePressed
}; // mouseListener
this.addMouseListener(l);
// 为当前面板添加鼠标监听
while (true) {
switch (state) {
case START: {
break;
}
case RUNNING:
// 熊猫进行移动
pander.pstep();
lang.move();
guaiShou.move();
for (int i = 0; i < 5; i++) {
jinBi[i].move();
}
// 熊猫下落边界
if (pander.y >= 570) {
pander.y = 570;
}
for (int i = 0; i < 5; i++) {
if (jinBi[i].score(pander)) {// 无法在数组类型中调用??
// 此处实现金币消失
jinBi[i].x = -900; // 让金币的位置移动到窗口外,达到金币消失的效果
jinBi[i].y = -900;
System.out.println("得分" + i);
}
}
// 判断碰撞
if (lang.hit(pander) || guaiShou.hit(pander)) {
// System.out.println("撞到了狼!");
state = GAMEOVER;
}
break;
case GAMEOVER: {
break;
}
}
for (int i = 0; i < 30; i++) {
xueHua[i].move();
}
repaint();// 重新画 ,刷新
Thread.sleep(50);
} // 对应while
}
}
// 金币只有在首次会出现,循环再次玩时没有金币出现????
Pander:
package day02;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Pander {
int x;
int y;
Image[] pimg;//锟斤拷锟斤拷没锟斤拷(锟斤拷锟叫伙拷锟藉功锟斤拷 锟斤拷锟斤拷 ) pimg锟斤拷锟斤拷
double g;//锟斤拷锟斤拷锟斤拷锟劫讹拷
double t;
double v;
double v0;
double vs;
double s;
int width;
int height;
public Pander(){
//自由落体运动
g=2.2; //加速度
t=1.1; //时间
v=0; //实时速度
s=0; //位移
v0=0; //初速度
vs=40;
width=60;
height=98;
x=300;
y=570;
pimg =new Image[4];
for(int i=0;i<pimg.length;i++){
pimg[i]=new ImageIcon("Images02/熊猫0"+i+".png").getImage();
}
}
public void pstep(){
s=v0*t-(g*t*t/2);
v=v0-g*t;
v0=v;
y=(int)(y-s);
}
public void jump(){
v0=vs;
System.out.println(vs);
}
}
Road:
package day02;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Road {
int x;
int y;
Image road;
public void move() { //背景图片向右移动,熊猫角色原地改变图片
x = x + 2;
if (x > 1280) {
x = 0;
}
}
public Road() {
x = 0;
y = 620;
road = new ImageIcon("Images02/路.jpg").getImage();
}
}
Sign:
package day02;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Sign {
int x;
int y;
Image sign;
public Sign() {
x = 118;
y = 15;
sign = new ImageIcon("Images02/冰雪大作战.jpg").getImage();
}
}
Snow:
package day02;
import java.awt.Image;
import java.util.Random;
import javax.swing.ImageIcon;
//属性-本身具有的(声明变量)
public class Snow {
int x;
int y;
int xStep;
int yStep;
Image snow;
Random r;// 随机
// 方法-能做什么
public void move() {
y += yStep;
x += xStep;
xStep = xStep * -1;// 使雪左右移动
if (y > 620) {// 触底反弹
y = 0;
}
// }
}
// 构造方法-初始化属性使用的(给变量赋值) 不能在声明时给变量赋值么?
public Snow() {
r = new Random();
xStep = 1;
yStep = 2;
x = r.nextInt(1280);
y = 0 -r.nextInt(720);// 从屏幕上端开始出现雪花
snow = new ImageIcon("Images02/snow-sheet0.png").getImage();
}
}
Wolf:
package day02;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Wolf {
int x;
int y;
Image[] wolf;
int width;
public Wolf() {
x = 1500;
y = 585;
width = 93;
wolf = new Image[6];
for (int i = 0; i < wolf.length; i++) {
wolf[i] = new ImageIcon("Images02/狗" + (i + 1) + ".png").getImage();
}
}
public void move() {
//窗口宽度是1280 , 让狼从1500出向左走,走出窗口时又回到1500处
x = x - 10;
if (x < -45) {
x = 1500;
}
}
// 定义判断碰撞方法
public boolean hit(Pander pander) {
if (pander.y + pander.height > y) {
if (pander.x + pander.width > x && pander.x < x + width) {
return true;
}
}
return false;
}
}
World:
package day02;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class world {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
JFrame f00 = new JFrame();
f00.setSize(1280, 720);
f00.setTitle("熊猫大战冰雪世界");
f00.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel p00 = new MyPanel();
f00.add(p00);
f00.setVisible(true);
int i = 0;
p00.action();
}
}
游戏到此就完成了。
这个游戏是我朋友所写,并非本人。特此声明。