Java写的第一个小游戏(续)

优化代码(数据维护):

注:此为小游戏最终版本 代码做到最优最简

  • 基于之前发表的文章详情可见

    点击查看前文

  • 回顾之前的代码我们可以看到很多的固定常量值或是属性我们都会大量的重复使用,这并不符合我们代码简洁易懂的特点

  • 所以我们可以把重复出现的量或是属性或是方法使用面向对象的思想,减少代码的冗余使代码简单明了

1.创建项目(GreenHat)

2.在项目(GreenHat)下插入我们使用的图片文件(images)

3.在src(源代码)下创建游戏包(com.ytzl.ylm)

4.在游戏包(com.ytzl.ylm)下创建客户端类(GameClient)以做运行游戏的基础

5.在游戏包下创建项目涉及到类的包(entity)

5.实现游戏窗口

     5.1让客户端类(GameClient)继承Frame类:
public class GameClient extends Frame{ }

关于Farme类:
1.Farme类是Java自带的一个系统类
2.Farme类的作用是可以制作出带有标题和边框的顶层窗口

     5.2在类包(entity)下创建一个超类(SuperSoulEntity)以存放复用的属性以及代码,减少代码冗余
     5.3在超类下定义之后会多次使用到的窗体的 宽 高
//窗体宽度public static final int CLIENT_WIDTH = 700;//窗体高度public static final int CLIENT_HEIGHT = 500;

使用static定义 以便在其他类调用属性

     5.4在客户端类中写游戏运行方法
// 运行游戏方法public void start() {//开始游戏时在控制台输出显示内容System.out.println("游戏马上开始,请玩家做好准备");//设置窗体标题this.setTitle("原谅帽带战");//设置窗体的大小以及位置this.setBounds(0, 0, SuperSoulEntity.CLIENT_WIDTH, SuperSoulEntity.CLIENT_HEIGHT);// 让窗体显示出来this.setVisible(true);//点击窗口x关闭键响应关闭this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent windowEvent) {//点击X退出游戏后在控制台输出显示内容System.out.println("Game Over!!!");//调用System类中的exit方法以实现窗口关闭按钮(X)的生效System.exit(0);}});
     5.5在客户端类中写main方法调用游戏运行方法,实现游戏的运行
//定义main方法以开始运行游戏public static void main(String[] args) {GameClient gameClient = new GameClient();gameClient.start();}
  • 实现后效果
    在这里插入图片描述

6.给窗口添加背景图片

     6.1在超类中定义读取图片的方法以插入图片
//读取图片方法getImagepublic static Image getImage(String imgPath) {//参数为图片路径地址ImageIcon imageIcon = new ImageIcon(imgPath);return imageIcon.getImage();}
     6.2在客户端类中实现背景图片的插入
	// 常量 定义背景图片的路径public static final String BG_PATH = "images/bg.png";// 定义一个图片的静态变量private static Image image;// 把路径的值给静态变量,所有资源(图片,音频,视频)只需要加载一次static {image = SuperSoulEntity.getImage(BG_PATH);}//重写父类Frame类的paint方法以实现插入各种图片@Overridepublic void paint(Graphics g) {// 画背景图g.drawImage(image, 0, 0, SuperSoulEntity.CLIENT_WIDTH, SuperSoulEntity.CLIENT_HEIGHT, this);}
  • 实现后效果图
    在这里插入图片描述

7.插入人物图片

     7.1在类包(entity)下创建人物类(Buffon)
     7.2在超类中写人物用到的属性以及方法
	//x坐标protected int x;//y坐标protected int y;//宽protected int width;//高protected int height;//移动速度protected int speed;//游戏窗体属性 使图片在窗体中显示protected GameClient gameClient;//全参构造    给图片属性赋初始值public SuperSoulEntity (int x,int y,int width,int height,int speed,GameClient gameClient) {this.x = x;this.y = y;this.width = width;this.height = height;this.speed = speed;this.gameClient = gameClient;}
     7.3在人物类中写相应的方法以及属性
// 人物图片属性public static Image buffoonImage = SuperSoulEntity.getImage("images/body/s-left.png");//带参构造public Buffoon(int x, int y, GameClient gameClient) {super(x, y, 50, 50, 5, gameClient);}//小丑有自己的画画方法public void paint(Graphics g) {g.drawImage(buffoonImage, this.x, this.y, this.width, this.height, this.gameClient);}
     7.4在客户端类中实现插入人物图片
//重写父类Frame类的paint方法以实现插入各种图片@Overridepublic void paint(Graphics g) {// 将人物插入窗口buffoon.paint(g);}
  • 实现效果:
  • 在这里插入图片描述

8.实现人物移动

     8.1定义图片移动涉及的属性
	// 人物-状态(初始值为静止)private String dir = "STOP";// 人物-方向private String dir1 = "UP";//判断方向按键是否同时按下了两个组合键(斜方向移动)默认四个方向都没有被按下boolean up = false;boolean right = false;boolean left = false;boolean down = false;
     8.2定义人物-状态的get set方法
//get set方法public String getDir() {return dir;}public void setDir(String dir) {this.dir = dir;}
     8.3在游戏包下创建线程包(thread)并创建线程类(RepaintTread)接口Runnable,以实现人物图像的移动
/*** 线程类(重新绘制画图的线程)*/
public class RepaintThread implements Runnable{public RepaintThread(GameClient gameClient) {this.gameClient = gameClient;}// 游戏窗体private GameClient gameClient;@Overridepublic void run() {while (true){// 每50毫秒执行一次try {Thread.sleep(50);// 重新绘制图像gameClient.repaint();} catch (InterruptedException e) {e.printStackTrace();}}}
}
     8.4在人物类写相关的移动方法
// 确定键盘按下时的人物移动方向public void okDirPrssed(int keyCode) {// 确定方向switch (keyCode) {case KeyEvent.VK_UP:System.out.println("向上走!");// 按向上箭头,给人物的方向设置为向上this.setDir("UP");// 当按住下方向键时,监听为true(已按下)up = true;break;case KeyEvent.VK_DOWN:System.out.println("向下走!");// 按向下箭头,给人物的方向设置为向下this.setDir("DOWN");// 当按住下方向键时,监听为true(已按下)down = true;break;case KeyEvent.VK_LEFT:System.out.println("向左走!");// 按向左箭头,给人物的方向设置为向左this.setDir("LEFT");// 当按住下方向键时,监听为true(已按下)left = true;break;case KeyEvent.VK_RIGHT:System.out.println("向右走!");// 按向右箭头,给人物的方向设置为向右this.setDir("RIGHT");// 当按住下方向键时,监听为true(已按下)right = true;break;}//判断用户到底按了那些键//东北if (up && right) {this.setDir("UR");}//东南if (right && down) {this.setDir("DR");}//西北if (left && up) {this.setDir("LU");}//西南if (left && down) {this.setDir("LD");}}/*** 键盘松开,确定人物移动方向*/public void okDirReleased(int keyCode) {switch (keyCode) {//上case KeyEvent.VK_UP:up = false;break;//下case KeyEvent.VK_DOWN:down = false;break;//左case KeyEvent.VK_LEFT:left = false;buffoonImage = SuperSoulEntity.getImage("images/body/s-left.png");break;//右case KeyEvent.VK_RIGHT:right = false;buffoonImage = SuperSoulEntity.getImage("images/body/s-right.png");break;}if (!up&&!down&&!left&&!right){this.setDir("STOP");}}/*** 人物移动*/public void move(String dir) {if ("UP".equals(dir)) {this.y -= this.speed;dir1="UP";}if ("RIGHT".equals(dir)) {this.x += this.speed;dir1="RIGHT";}if ("DOWN".equals(dir)) {this.y += this.speed;dir1="DOWN";}if ("LEFT".equals(dir)) {this.x -= this.speed;dir1="LEFT";}if ("UR".equals(dir)) {this.x += this.speed;this.y -= this.speed;dir1="UR";}if ("DR".equals(dir)) {this.x += this.speed;this.y += this.speed;dir1="DR";}if ("LD".equals(dir)) {this.x -= this.speed;this.y += this.speed;dir1="LD";}if ("LU".equals(dir)) {this.x -= this.speed;this.y -= this.speed;dir1="LU";}}
     8.5在客户端类中实现人物移动(补充游戏运行方法)
// 运行游戏方法public void start() {//开始游戏时在控制台输出显示内容System.out.println("游戏马上开始,请玩家做好准备");//设置窗体标题this.setTitle("原谅帽带战");//设置窗体的大小以及位置this.setBounds(0, 0, SuperSoulEntity.CLIENT_WIDTH, SuperSoulEntity.CLIENT_HEIGHT);// 让窗体显示出来this.setVisible(true);//点击窗口x关闭键响应关闭this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent windowEvent) {//点击X退出游戏后在控制台输出显示内容System.out.println("Game Over!!!");//调用System类中的exit方法以实现窗口关闭按钮(X)的生效System.exit(0);}});// 监听键盘事件this.addKeyListener(new KeyAdapter() {//当键盘按下时触发@Overridepublic void keyPressed(KeyEvent e) {// 获取被按下的键的对应数值  如:A-67,B-68int keyCode = e.getKeyCode();// 调用人物确定方向的方法okDirbuffoon.okDirPrssed(keyCode);buffoon.move(buffoon.getDir());}//当键盘松开时触发@Overridepublic void keyReleased(KeyEvent e) {//获取松开的按键的值int keyCode = e.getKeyCode();buffoon.okDirReleased(keyCode);}});//开启重新绘制线程RepaintThread repaintThread = new RepaintThread(this);// 创建车间工人Thread thread = new Thread(repaintThread);// 工人听候调度thread.start();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/353103.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

java小游戏超级玛丽:06.第二关的设计

第二关预览图: 判断是否为第二关 if (sort 2) {} 砖块位置图: 砖块坐标: A(240,390) B(270,360) C(300,330) D(270,360) E(300,360) F(330,390) G(360,360) H(390,390) I(420,390) f1(240,300) 空1(420,270&a…

java小游戏超级玛丽:07.第三关的设计

第三关预览图 砖块位置图: 砖块坐标: A(290,390) B(320,360) C(350,330) D(320,390) E(350,480) F(350,390) G(380,300) H(380,330) I(380,360) J(380,390) K(410,270) L(410,300) M(410,330) N(410,360) O(410,390) P(60,390) Q(90,360) R(90…

【Java十大热门游戏合集】Java经典游戏项目

家人们,今天我们来看一下学Java必练的10款游戏项目! 大家都知道学习编程必须要做的就是敲代码和做项目练手了,那项目有难有易,很多小伙伴不知道从哪里找项目来练习,今日我们来看一下初级项目中都有哪些能让我们来练手…

Java游戏开发——开心农场

游戏介绍: “开心农场”是一款以种植为主的社交游戏。用户可以扮演一个农场的农场主,在自己的农场里开垦土地,种植各种水果蔬菜。本次开发了一个“开心农场”游戏,运行程序,效果如下图所示。鼠标先选定指定土地&#…

JAVA 实现《超级玛丽》游戏

前言 在你的童年记忆里,是否有一个蹦跳、顶蘑菇的小人? 如果你回忆起了它,你定然会觉得现在它幼稚、无聊,画面不漂亮,游戏不精彩……但请你记住:这才是真正的游戏,它给了你无限的欢乐&#xf…

Java游戏开发——连连看

游戏介绍: “连连看”是一款来源于我国台湾的桌面小游戏,主要考验的是玩家们的眼力,在有限的时间内,只要能把所有能连接的相同图案,两个两个的找出来,每找到一对,它们就会自动消失,只…

java小游戏超级玛丽:05.第一关的设计

第一关效果图: 目录 判断是否为第一关 绘制第一关的场景 绘制地面(for循环) 绘制砖块 绘制水管 生成Obstatic列表的getter方法 绘制障碍物 判断是否为第一关 if(sort 1){ } 在上面有定义变量sort 绘制第一关的场景 绘制地面&…

程序员从0到收获心仪offer,我靠训练营实现了180度逆袭!

我相信,在未来的职场中,我也能通过这段时间养成的学习习惯和生活习惯让自己一步步成为更好的自己,以自己为荣 我在大学里主修计算机科学与技术,一个普通的院校,一个算是常见的专业,我知道我的学历和一些其他…

10 【组件编码流程 组件自定义事件 全局事件总线】

1.组件编码流程 组件化编码流程: ​ (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。 ​ (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用: ​ 1…

QQ互联地址 中注册的QQ开发者 在哪里提交审核?

QQ互联地址:https://connect.qq.com 废话不说,直接上图: 有时点击后没反应,耐心 多试几次! 然后 就会看到 提交审核的表单了, 有没发现 这个提交审核的 链接藏的有点深!! 哈哈哈&am…

QQ小程序打开指定QQ群

官方提供了接口&#xff1a; <view class"footer"><button open-type "openGroupProfile" class"footer-tips" group-id"620033746">v1.0 by&#xff1a;IWH <text>加群玩&#xff01;</text></button&g…

打开图片链接直接打开QQ对话框

<a href"tencent://message/?uin7530****&SiteQQ交谈&Menuyes" target"blank"> <img border"0" src"http://wpa.qq.com/pa?p1:7530*****:7" alt"有事Q我吧" width"71" height"2…

QQ的分享

使用的sdk版本&#xff1a; V2.2.2&#xff08;发布日期&#xff1a;2014.3.17&#xff09; 弱弱的提醒下&#xff1a; 1.配置清单等环境搭建&#xff0c;这里就不多说了&#xff0c;可以去看看我的另外一篇博客&#xff0c;QQ的第三方登录&#xff0c;那里有介绍。 2.这里集…

QQ圈子:从哪里来,到哪里去

2019独角兽企业重金招聘Python工程师标准>>> 摆脱顿巴数的魔咒 社 交是人类的一个最基本的需求。但是&#xff0c;自然给我们人类的大脑&#xff0c;只能让我们维系150-200个左右的好友。超出这个范围&#xff0c;就会有好友慢慢地被淡忘。很多社会 群体的平均大小是…

html 打开腾讯qq,qq软件管理器 QQ应用管理器里面的腾讯软件打不开

手机QQ中的消息管理器在哪里 打开的qq软件主界面&#xff0c;点击左下角的“主菜单”按钮。 在打开的qq主菜单中&#xff0c;点击“设置”菜单项。 手机版qq怎么进消息管理器QQ右下角...有一个查找。 查找的左边,有一个小喇叭. 那个就是信息管理器。 腾讯qq上的应用管理器在哪 …

打开qq聊天界面的url

2019独角兽企业重金招聘Python工程师标准>>> 打开qq聊天界面的url 北极熊爱企鹅 10:43:39 NSString *open_URL "mqq://im/chat?chat_typewpa&uin501863587&version1&src_typeweb"; 转载于:https://my.oschina.net/LiuChongYang/blog/51829…

如何创建圈子

首先您需要登录您在CSDN Blog的个人管理后台,点击“圈子”.如图所示: 点击"创建一个新的圈子" 输入名称和标题&#xff08;名称将是URL的一部分&#xff0c;例如experts就是 http://blog.csdn.net/group/experts/的名称&#xff1b;而“CSDN专家群”则是标题&#x…

Numpy---创建多维数组、创建正态分布、创建均匀分布

1. 创建一个随机整数的多维数组 np.random.randint(low, highNone, sizeNone, dtypel) 参数说明: low : 最小值 highNone: 最大值 highNone时&#xff0c;生成的数值在【0, low&#xff09;区间内 如果使用high这个值&#xff0c;则生成的数值在【low, high&#xff09;区…

扩容系统盘【centos-root】

问题描述&#xff1a; 磁盘空间有42G&#xff0c;但是系统盘只有6G。 问题抛出&#xff1a;&#xff08;P2原本只有7G&#xff0c;其中有30G错误分配到nvmeOn1p2了&#xff09;p2的30G空间怎么合理分配给系统盘? &#xff08;执行&#xff1a; sudo growpart /dev/nvme0n1 …

华为od机试题目回顾

今天去做了华为机试&#xff0c;两道一星题&#xff0c;一道二星题。 一星题 1&#xff1a; 题目主要大意&#xff1a; 输入一串字符串&#xff0c;里面可能包含有(x,y)的坐标。 0<x<1000&#xff0c;0<y<1000&#xff0c;类似(01,1)、(1,01)、(0,100)的都是非法坐…