射击类小游戏讲解:太空大战
相信不少人都玩过太空大战,版本不同,原理相同。没玩过的看下图了解一下:
首先先分解一下游戏的构成:
- 大批敌军
- 子弹
- 保卫机
这三个角色之间基本的互动请看流程图
基本流程图
以上是基本的操作流程图,具体实现的源码将在文章最后的小结
部分给大家
代码实现难点讲解
我把我认为可能需要考虑的问题归类如下:
如何实现并发?
- 实现多线程总是绕不开
Runnable
和Thread
,但是我们今天不调用Thread,只用runnable,而且不是继承。除此之外,今天用的package不是大家常知的java.awt.*
而是javafx.scene.*
。
- 实现多线程总是绕不开
三个角色运动状态不同,如何初始化用同一个类调用?
- 很简单,虽然运动轨迹不同,但是基本的变量:当前位置,速度,尺寸都是可以从同一个构造函数初始的。这里我们介绍以下源码作者Joe Finney的构造办法:
public class Shape
{//在这之前你需要要个最基础的图形构造类,除非你不想创造复杂的图形或者直接想调用图像//这边的长方形可以理解位积木private Rectangle[] p = new Rectangle[50];private int number = 0;private double xPosition = 0.0;private double yPosition = 0.0;//给图形声明初始的位置,需要考虑一下原本图像的尺寸,位置太高或太低都会看不到完整的图形public Shape(double x, double y){this.xPosition = x;this.yPosition = y;}//把新的积木拼到原有的积木上,也可以使用arraylist实现public void addRectangle(Rectangle r){if (number < p.length){p[number] = p;number++;} }//以上都是静态的而且不会在画面上显示//addShapeTo方法帮助我们把积木们放到屏幕里public void addShapeTo(GameArena a){for (int i = 0 ; i < number; i++){p[i].setXPosition(p[i].getXPosition() + xPosition);p[i].setYPosition(p[i].getYPosition() + yPosition);a.addRectangle(p[i]);}}//移动积木堆们,根据我们给定的速度。积木堆们以整体的形式运动public void move(double x, double y){xPosition += x;yPosition += y;for (int i=0; i<numberParts; i++){p[i].setXPosition(p[i].getXPosition() + x);//注意,在屏幕里表示向右p[i].setYPosition(p[i].getYPosition() + y);//注意,在屏幕里表示向下}}//如名字所写,带有目的性,表示直接移动到指定的位置//在这边的作用是子弹打出去后最后又回到原来的位置,因为速度很快,所以屏幕上看不到回来的效果//感觉子弹好辛苦,但是不想给子弹单独建个数组了,麻烦子弹了...public void moveTo(double x, double y){move(x-xPosition, y-yPosition);xPosition = x;yPosition = y;}//获取第i个积木public Rectangle getP(int i){return p[i];}//判断两个积木快是否相撞boolean collides (Shape c){for (int i=0; i<number; i++){for (int j=0; j<c.number; j++){if (p[i].collides(c.getP(j)))//这个调用的是Rectangle里的方法,不是这个类里的return true;}}return false;}public double getXPosition(){return xPosition;}public double getYPosition(){return yPosition;}public void removeShapeFrom(GameArena a){for (int i=0; i<number; i++){a.removeRectangle(p[i]);}}
}
界面效果
小编之前说了,如果你想引用现有的图像做你的角色....
原理和上面的代码差不多,不拼积木肯定比拼积木轻松的,所以我们只要创造图像类。
以下是小编的源码
/**
* @author Hephaest
*/
//没错!什么类都没import!
public class ImageView
{private double xPosition; private double yPosition; private double width; private double height; private String url;private ImageView[] part = new ImageView[100];private int numberPart = 0;public double getXPosition(){return xPosition;}public double getYPosition(){return yPosition;}public void setXPosition(double x){this.xPosition = x;}public void setYPosition(double y){this.yPosition = y;}public double getWidth(){return width;}public double getHeight(){return height;}public String getUrl(){return url;}//定义图像的时候需要位置,尺寸,还有哪里来的图public ImageView(double x, double y, double w, double h, String url){xPosition = x;yPosition = y;width = w;height = h;this.url = url;} //碰撞的算法小编没优化public boolean collides(ImageView i){return (xPosition < i.xPosition + i.width &&xPosition + width > i.xPosition &&yPosition < i.yPosition + i.height &&yPosition + height > i.yPosition);}//运动的方法和之前的一致public void move(double x, double y){xPosition += x;yPosition += y;for (int i=0; i<numberPart; i++){part[i].setXPosition(part[i].getXPosition() + x);part[i].setYPosition(part[i].getYPosition() + y);}}public void moveTo(double x, double y){move(x-xPosition, y-yPosition);xPosition = x;yPosition = y;}public void removeShapeFrom(GameArena a){for (int i=0; i<numberPart; i++){a.removeImage(part[i]);}}
}
界面效果
补充
最后至于图形界面框那部分,以前鼠标操控的办法,请参考原作者的javafx
使用办法。小编为了利用javafx实现图像移动绞尽脑汁。不过最终还是找到办法了:
/**
*@author Joe Finney
*override by hephaest
*/
//用hashmap 创造ImageView的数组对象,因为ImageView是节点private Map<ImageView, javafx.scene.image.ImageView> images = new HashMap<>();@overrideprivate void frameUpdate (){if (!this.exiting){// Remove any deleted objects from the scene.synchronized (this){for (Object o: removeList){if (o instanceof Rectangle){Rectangle r = (Rectangle) o;javafx.scene.shape.Rectangle rectangle = rectangles.get(r);root.getChildren().remove(rectangle);rectangles.remove(r);}//我自己添加的if (o instanceof ImageView){ImageView i = (ImageView) o;javafx.scene.image.ImageView image = images.get(i);root.getChildren().remove(image);images.remove(i);}}removeList.clear();// Add any new objects to the scene.for (Object o: addList){if (o instanceof Rectangle){Rectangle r = (Rectangle) o;javafx.scene.shape.Rectangle rectangle = new javafx.scene.shape.Rectangle(0, 0, r.getWidth(), r.getHeight());root.getChildren().add(rectangle);rectangles.put(r, rectangle);}//我自己添加的if (o instanceof ImageView){ImageView i = (ImageView) o;javafx.scene.image.ImageView image = new javafx.scene.image.ImageView(i.getUrl());root.getChildren().add(image);images.put(i, image);}}addList.clear();}for(Map.Entry<Rectangle, javafx.scene.shape.Rectangle> entry : rectangles.entrySet()){Rectangle r = entry.getKey();javafx.scene.shape.Rectangle rectangle = entry.getValue();rectangle.setTranslateX(r.getXPosition() - r.getWidth()/2);rectangle.setTranslateY(r.getYPosition() - r.getHeight()/2);rectangle.setFill(getColourFromString(r.getColour()));}//我自己添加的for(Map.Entry<ImageView, javafx.scene.image.ImageView> entry : images.entrySet()){ImageView i = entry.getKey();javafx.scene.image.ImageView image = entry.getValue();image.setTranslateX(i.getXPosition() - i.getWidth()/2);image.setTranslateY(i.getYPosition()- i.getHeight()/2);image.setImage(new Image(i.getUrl()));}}}
除此之外,addImage和removeaddImage只要改个变量名字就好了。
小结
这几天摸索的经验总结:
- API很重要!学会查javadoc!
- 如果想做游戏开发还是用java.awt.*吧
相关代码分享
github完整源码链接:Thanks to finneyj
Oracle-avafx.scene.image Javadoc:javafx.scene.image
射击类小游戏讲解:太空大战相关推荐
- HTML5/Canvas太空射击类小游戏源码
下载地址 JavaScript HTML5/Canvas太空射击类小游戏源码,非常值得学习的一款js射击小游戏代码,美术有点老旧,但是代码是完全开源的,有参考价值. dd:
- HTML5 Canvas 射击类小游戏 平滑的移动 思路
这篇博客主要讲了如何处理HTML5 Canvas 游戏中的角色移动问题. 笔者这几天做了一个 HTML5 Canvas 的射击类小游戏,嗯,名字叫做<DroppingBalls>,大概就是 ...
- 【cocos2d游戏开发实战】一款射击类小游戏《Zombie Age》的开发(一)
前言 因为学习的原因需要完成一款射击类的小游戏,之前做的飞机大战没有达到要求,在网上找了几款射击类游戏后因为素材和难度的关系最后决定山寨一下<僵尸时代2>这款小游戏,开发到游戏主体基本完整 ...
- [安卓] 12、开源一个基于SurfaceView的飞行射击类小游戏
前言 这款安卓小游戏是基于SurfaceView的飞行射击类游戏,采用Java来写,没有采用游戏引擎,注释详细,条理比较清晰,适合初学者了解游戏状态转化自动机和一些继承与封装的技巧. 效果展示 ...
- c语言射击类小游戏任务书,(c语言课程设计报告小游戏“石头剪子布”.doc
(c语言课程设计报告小游戏"石头剪子布" <C语言课程设计>报告 题目:石头剪子布 班级: 学号: 姓名: 指导教师: 成绩: 目 录: 一.选题背景- 3 - 二.设 ...
- 射击类小游戏——坦克大战(java实现)
项目名称:坦克大战 项目背景:坦克大战是一款非常经典的游戏,也是学习面向对象编程的理想实例.现在面向对象的计算机编程语言很多,很多想法都可以通过编程来实现.本文的坦克大战有完整的界面,能够实现人机大战 ...
- C#射击类小游戏简单思路及代码
博主想做一个小时候玩的FC坦克大战的游戏,然后先写点简单的来整理一下设计思路.然后今天就写了一个非常简单的游戏框架,300行左右代码,最简单的功能可以实现.源码可以在博主的资源页下载 https:// ...
- 《游戏学习》| 射击类小游戏 html5 打野鸭子
整合游戏是由html.js. css等代码完成的,无后端数据保存功能. 项目目录 css 文件夹是游戏样式控制文件 js文件夹是游戏事件控制文件 sounds文件夹是游戏声音控制文件 sprites ...
- 【Unity学习笔记】大三下学期 射击类小游戏制作
虽然大二寒假做过一次,但已经快忘光光了.. 所以这次要认真记录一下知识点! //0415更新 新添实现敌机生成.单例模式添加音乐特效等 //0408更新 总共实现了背景轮播.控制飞机走动.发射子弹的功 ...
最新文章
- php调用接口接口代码无法执行,php调用c接口无错版介绍
- office文件已损坏 该服务器,Office文件可能已损坏处理方法
- Java 中引用类型
- koding.com 使用putty
- 精品 IDEA 插件大汇总!值得收藏
- revit对齐命令选不中_如何利用无人机+Photoscan+Revit完成土方计算
- JavaScript中的私有函数;Javascript构造函数的私有方法中访问其属性和公有方法
- html菜鸟ruby,ruby的基础语法
- c语言实现统计过程控制,SPC统计过程控制
- nanoCAD Pro 10.0.4447.1969 Build 4520中文免费版
- 《CSS权威指南》读书笔记4
- 《中国人史纲》读书笔记:第六、七章 纪元前八、七世纪
- 谁挡道就骂谁,这个暴躁版扫地机器人火了,东北话也可以,网友:想劈了它...
- 深入浅出 - Android系统移植与平台开发(四)- Android启动流程
- CentOS7安装IT资产管理系统Snipe-IT
- NLP入门之——Word2Vec词向量Skip-Gram模型代码实现(Pytorch版)
- 晨风机器人发送图片_晨风机器人基本使用说明
- 10月25日 c语言 读取7个数(1—50)的整数值,每读取一个值,程序打印出该值个数的*
- 区块链1——区块链基础
- soul 网关源码解析