java setlocation为什么不动_基于Swing的Java小游戏——吃热狗

一、整体思路

  1. 继承窗体类,复写窗体刷新
  2. 添加按键监听
  3. 游戏结束界面
  4. 王思聪类和热狗类 移动轨迹计算
  5. 判断碰撞 音乐播放
  6. 不断刷新窗体 处理细节

二、编码

1.图片

首先你要找到图片,可以百度一张,然后用ps切开,再找一张背景图片就搞定了(一张为活动角色,就是你方向键控制的角色,一个自动的角色,也就是“热狗”)

ee77ecfb29e49198c25814095bcce591.png

活动角色

2491af95e35b30f8f5c97098cb8fee1a.png

得分

你还需要一个加载图片的工具类,可以使用getResource得到图片的URL路径,然后使用java自带的工具类ImageIO来读取图片

public class GameUtil { public static Image getImage(String path){URL url=GameUtil.class.getClassLoader().getResource(path);BufferedImage img=null;try {img = ImageIO.read(url);} catch (IOException e) {e.printStackTrace();}return img;}}

2.窗体

写一个类来继承窗体,为其设置宽高,位置,关闭设置,可否缩放大小

复写它的更新和绘画方法,以后要在里面写绘画思聪和热狗和碰撞判断逻辑

为其添加按键监听事件,在这里处理按键的点击和释放,以此来实现思聪的移动

public void launchFrame(){setSize(width,height);setResizable(false);setLocation(200,20);setVisible(true);addKeyListener(new KeyMoniter());addWindowListener(new WindowAdapter(){@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}         @Overridepublic void paint(Graphics graphics) {}@Overridepublic void update(Graphics g){} class KeyMoniter extends KeyAdapter{@Overridepublic void keyPressed(KeyEvent e) {            //按键按下}@Overridepublic void keyReleased(KeyEvent e) {    //按键抬起}}

3.思聪和热狗

首先要有一个位置,还要能移动,其实也就是不断的计算位置和把图片画上去的过程

定义一些思聪的属性,并在构造方法中初始化这些属性

boolean left,right,down,up;public int x,y,width,height;Image img ; public Plane(String img_path,int x, int y){this.img = GameUtil.getImage(img_path);this.x = x;this.y = y;width = img.getWidth(null);height = img.getWidth(null);live = true;}

把思聪画上去

public void draw(Graphics g){if(live){g.drawImage(img, x, y, null);move();}}

接下来最重要的就是计算思聪的位置了,为什么要把位置计算写到画思聪的方法里呢?主要是考虑这样的一种情况,如果你把方法计算写到按键按下或者释放里面,那么你想移动思聪的位置就得疯狂按键盘,要想长按按键来控制移动就要吧移动方法写到画思聪的方法里面,然后用按键的按下和释放来控制是否移动。

移动的时候还要考虑到边界的情况

public void move(){if(left&&x>=10){x -= 10;}if(up&&y>=30){y -= 10;}if(right&&x<=FeiJiGame.width-60){x += 10;}if(down&&y<=FeiJiGame.height -60){y += 10;}} public void KeyPressedControlDirection(KeyEvent e){int key_code = e.getKeyCode();if(key_code == 37){left = true;}if(key_code == 38){up = true;}if(key_code == 39){right = true;}if(key_code == 40){down = true;}} public void KeyRelasedControlDirection(KeyEvent e){int key_code = e.getKeyCode();if(key_code == 37){left = false;}if(key_code == 38){up =false;}if(key_code == 39){right = false;}if(key_code == 40){down = false;}}

最后提供两个方法来改写思聪的生存

对于热狗类就简单多了,就是让它不断的跑,不需要响应按键事件

定义一些属性和在构造方法中初始化

double speed=15;double degree; public double x,y;public int width,height;Image img; public Bullet(String img_path){img=GameUtil.getImage(img_path);degree = Math.random()*Math.PI*2;x=FeiJiGame.width/2;y=FeiJiGame.height/2;width = 10;height = 10;}

随机的degree的用途是让它们的初始方向不同,使用sin和cos函数来控制热狗的移动,同时也要注意边界

public void draw(Graphics g){g.drawImage(img, (int)x, (int)y, null);x += speed*Math.cos(degree);y += speed*Math.sin(degree); if(x>FeiJiGame.width-width||xFeiJiGame.height-height||y

4.碰撞检测和音乐播放

在java的awt里面有一个矩形类可以判断两个矩形是否有重叠部分,有重叠说明就碰撞上了

Rectangle bulletRectangle = new Rectangle((int)bullet.x,(int)bullet.y,bullet.width,bullet.height);Rectangle planeRectangle = new Rectangle(plane.x,plane.y,plane.width,plane.height);boolean collide= bulletRectangle.intersects(planeRectangle);

音乐播放可以使用第三方的库,jl-1.0.1.jar,因为可能连续吃到热狗,所以需要多线程播放音乐

class MusicPlayer implements Runnable{@Overridepublic void run() {try {new Player(new FileInputStream(FeiJiGame.class.getClassLoader().getResource("raw/music.mp3").getPath().substring(1))).play();} catch (Exception e) {e.printStackTrace();}}}

5.完成

剩下的就是窗体的刷新,这个可以开一个线程来做

class PaintThread extends Thread {@Overridepublic void run() {while(!Thread.currentThread().isInterrupted()){repaint();try {Thread.sleep(40);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}}

游戏右上方要显示现在的游戏时间,结束也要显示一些文字信息,写了一个工具类

使用font控制字体,graphics.setFont设置字体,drawString画上去

public void printInfo(Graphics g,String message,int size,int x,int y){g.setColor(Color.white);Font f = new Font("宋体",Font.BOLD,size);g.setFont(f);g.drawString(message, x,y);}

游戏结束时显示一些信息,根据时间判断给出等级(可以随意设置,自定义分数和等级)

private void gameOver(Graphics graphics) {printInfo(graphics,"GAME OVER",80,270,300);int survivalTime = (int)(endTime.getTime()-starTime.getTime())/1000;printInfo(graphics,"吃热狗时间:"+survivalTime+"秒",40,300,400); switch(survivalTime/10){case 1:printInfo(graphics,"独孤求败",50,350,500);break;case 2:printInfo(graphics,"登堂入室",50,350,500);break;case 3:printInfo(graphics,"小有成就",50,350,500);break;default:printInfo(graphics,"初入江湖",50,350,500);break;}paintThread.interrupt();}

在初始化窗体时要添加热狗和开始重绘线程,开始计时

for(int i=0;i<15;i++){Bullet bullet = new Bullet("images/hotdog.png");bulletList.add(bullet); }starTime = new Date();endTime = new Date();paintThread=new PaintThread();paintThread.start();

复写绘画和更新

        @Overridepublic void paint(Graphics graphics) {graphics.drawImage(bg, 0, 0, null);plane.draw(graphics);endTime = new Date();if(gameState){for(int i=0;i

在按键监听里面调用思聪的按键按下和释放方法

class KeyMoniter extends KeyAdapter{@Overridepublic void keyPressed(KeyEvent e) {plane.KeyPressedControlDirection(e);}@Overridepublic void keyReleased(KeyEvent e) {plane.KeyRelasedControlDirection(e);}}

最后启动游戏

public static void main(String[] args) {FeiJiGame game = new FeiJiGame();game.loadGame();}

6.注意事项

6.1 在加载lib下依赖包的时候,不同开发工具的引入方式不同,这里主要区别是eclipse和idea

6.2 在程序加载素材文件(背景和音乐等)需要对路径进行中文编码处理,否则路径会编程url编码,导致加载失败,如果路径是纯英文,就不需要考虑这些。

7.需要源码的可以私信或者留言

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值