- 浏览: 724988 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (168)
- CSS (1)
- Eclipse (4)
- English (1)
- ExtJS (1)
- Git (3)
- Grails (3)
- Groovy (2)
- Hadoop (7)
- HTML5 (2)
- JavaScript (3)
- Maven (2)
- MQ (5)
- MyBatis (3)
- NodeJS (6)
- NoSQL (4)
- Oracle (6)
- PDF (3)
- Python (9)
- Redis (17)
- Tomcat (2)
- Unix (8)
- Web Service (6)
- 安全 (1)
- 电子书 (6)
- 工具 (1)
- 其他 (21)
- 人工智能 (2)
- 视觉 (2)
- 算法 (6)
- 图表 (1)
- 网络 (13)
- 性能 (5)
- 游戏 (9)
- 字节码 (3)
- 机器学习 (1)
最新评论
-
lijunwyf:
cevin15 写道可以看下这个开源软件,https://gi ...
用markdown2html把md转换成html -
cevin15:
可以看下这个开源软件,https://github.com/c ...
用markdown2html把md转换成html -
Raina:
运行不了呢……提示错误无法加载主类Baiduwallpaper ...
用Java更换Windows桌面壁纸 -
苏城细雨沐秋风:
我把解码的jar添加到类路径后,mp3可以播放,但是flac和 ...
java播放mp3/ogg/ape/flac音乐 -
peishuai1987:
请问楼主现在怎么样了,读了很多源码吗,比如mybatis、sp ...
mybatis源码阅读心得
0.前言
本例子取自cping1982早期公开的一个STG源码,loon-simple-20090212,里面带了6个游戏。这次我们要分析的是STGSimple这个飞机游戏。截图如下:
出处请参见上半年私人计划简略及Java桌面游戏开发入门示例并源码集合
下载地址:http://code.google.com/p/loon-simple/downloads/list
声明一下,这个程序不是我写的,是cping1982写的。本人在这里斗胆分析一下高手5年前写的代码,一来是提高自己,二来也是给众多小白以信心和勇气,分析完源码你会发现用java写一个飞机或者坦克的游戏还是不难的。
如果你无法访问google code,也可在本文文末下载我已经加上了注释的版本。
下面进入正题。
1. Role 所有角色的基类
这个类是做STG游戏的关键,所有画面上的东东都是“角色”,包括玩家飞机,敌机,老板,子弹等等。于是把他抽象出来。三个方法move,checkHit,draw是关键。
以下是Role类的层次结构图,可以看到,一切东东都是Role的子类。
Battle是玩家飞机。
Enemy是敌人。
Hero是子弹。
当然类的命名好坏我们就不去评判了,意思到就行了。
2. Battle 玩家飞机
move方法,根据按下的方向键移动。
z,x来生成子弹(BattleBasic)或激光(BattleBeam)。
checkHit判断如果和别的角色碰撞,则扣减血,如果血为0,则死亡
3.Hero 子弹
Hero
|----BattleShot 玩家子弹
| |----BattleBasic 普通子弹
| |----BattleBeam 激光
|----EnemyShot 敌人子弹
|----CircleBullets 圆圈子弹
|----MoveAimingBullet 向玩家发射的子弹
|----......
4. 入口点 Main
STGFrame代码省略,就是嵌套一个GamePanel
5.GamePanel (骨架代码)
这个是整个飞机游戏的核心代码。
5.1 初始化
5.2 核心线程
可以看到核心线程就是一个死循环,根据不同的模式执行不同的逻辑。
模式表
然后关键就是用双缓冲技术画图,防止屏幕闪烁。
5.3 主程序
看一下stage1里面调用主程序gameMain
这里的碰撞检测便是关键了,2重嵌套循环,判断角色之间的两两碰撞。接下来每个角色移动。
可以说它便是许多游戏实现的关键所在。有了这个骨架代码,只要实现不同Role的checkHit和move还有draw方法就可以了,游戏的扩展性变得简单。
6. EnemyTable 敌人登场表
敌人什么时候出现,为了避免硬编码,于是定了一张表格,这个便是表格类。
7. 关卡设计
看到了吗,这样改关卡就变得容易多了,只要改最上面那个表格就ok了。其实做的更好的话可以提取到一个配置文件里。
8.各种敌人,子弹的设计
接下来就是开动你的想象力的时间了。结合各种数学,物理知识,做出千变万化的角色。
这里分析几个例子
8.1 EnemyA
下图分别是pattern 2 和pattern 3的运行轨迹,可以看到pattern2使用一个sin函数可以展现弧线的运动轨迹。而pattern3使用2个sin函数可以让敌机转圈。
8.2 MoveAimingBullet
这个类不错,敌人会朝着玩家发射出子弹,而不是乱放空枪,使得敌人少许有了一些AI。
如图,数学公式就是先算出敌我之间的距离,distance=sqrt(x^2+y^2)
然后放出的子弹的速度就是
vx=x/distance
vy=y/distance
8.3 CircleBullets
老版更厉害,可以放出一个圆圈的子弹。
9.总结
可以看到,用java做游戏并不难。这个例子可以作为新手做STG游戏(飞机大战,坦克大战)的一个起步。
当然这个例子是纯java,没有用任何框架。当代码膨胀了以后,可以考虑用一些游戏框架来解放我们的生产力。
另外,原作者cping1982的博客相当好,有许多java游戏编程的资料值得参考。
本例子取自cping1982早期公开的一个STG源码,loon-simple-20090212,里面带了6个游戏。这次我们要分析的是STGSimple这个飞机游戏。截图如下:
出处请参见上半年私人计划简略及Java桌面游戏开发入门示例并源码集合
下载地址:http://code.google.com/p/loon-simple/downloads/list
声明一下,这个程序不是我写的,是cping1982写的。本人在这里斗胆分析一下高手5年前写的代码,一来是提高自己,二来也是给众多小白以信心和勇气,分析完源码你会发现用java写一个飞机或者坦克的游戏还是不难的。
如果你无法访问google code,也可在本文文末下载我已经加上了注释的版本。
下面进入正题。
1. Role 所有角色的基类
这个类是做STG游戏的关键,所有画面上的东东都是“角色”,包括玩家飞机,敌机,老板,子弹等等。于是把他抽象出来。三个方法move,checkHit,draw是关键。
public abstract class Role { protected static GamePanel app; protected Image img; //图片 protected float x; protected float y; protected float WIDTH; protected float HEIGHT; private boolean dead; //是否死亡 //移动 abstract void move(); //碰撞检测 protected boolean checkHit(Role chara) { return x > chara.x - WIDTH && x < chara.x + chara.WIDTH && y > chara.y - HEIGHT && y < chara.y + chara.HEIGHT; } //把自己画出来 public void draw(Graphics g) { g.drawImage(img, (int) x, (int) y, app); } }
以下是Role类的层次结构图,可以看到,一切东东都是Role的子类。
Battle是玩家飞机。
Enemy是敌人。
Hero是子弹。
当然类的命名好坏我们就不去评判了,意思到就行了。
2. Battle 玩家飞机
public class Battle extends Role { //tamaIntCount防止子弹放的太快,要限制频率 private int tamaIntCount; //速度(按一次方向键移动的距离) private float speed; //3枚子弹的速度 //第1枚,(-1,-7),x少许向左,y快速向上 //第2枚,(0,-8),x不变,y快速向上 //第3枚,(1,-7),x少许向右,y快速向上 private float tv[] = { -1F, -7F, 0.0F, -8F, 1.0F, -7F }; //当前血量 public int power; //最大血量 public int powerMax; public void move() { if (Key.left) { //如果按下x键,减速移动,否则全速移动,如果移动超出屏幕,不让移出。上下左右分别重复处理 if (Key.xkey) x -= (double) speed / 4D; else x -= speed; if (x <= 0.0F) x = 0.0F; } //...... //以上是左键处理,其他3个方向类似,此处省略 //...... //如果按下z键,放出3枚子弹,tamaIntCount防止子弹放的太快,要限制频率 if (Key.zkey && tamaIntCount <= 0) { for (int i = 0; i < tv.length; i += 2) { GamePanel.addList(new BattleBasic(x + WIDTH / 2.0F, y, tv[i], tv[i + 1])); tamaIntCount = 8; } } //如果按下x键,放出1枚激光 if (Key.xkey && !Key.zkey && tamaIntCount <= 0) { GamePanel.addList(new BattleBeam(x + WIDTH / 2.0F, y, 0.0F, -8F)); tamaIntCount = 2; } } }
move方法,根据按下的方向键移动。
z,x来生成子弹(BattleBasic)或激光(BattleBeam)。
checkHit判断如果和别的角色碰撞,则扣减血,如果血为0,则死亡
public boolean checkHit(Role chara) { //此处判断并处理与敌机(EnemyA,B,C)或子弹(EnemyShot)碰撞的逻辑 if ((chara instanceof EnemyA) || (chara instanceof EnemyB) || (chara instanceof EnemyC) || (chara instanceof EnemyShot)) { if ((x + WIDTH) - 14F > chara.x && x + 14F < chara.x + chara.WIDTH && (y + HEIGHT) - 12F > chara.y && y + 12F < chara.y + chara.HEIGHT) { chara.dead(); power -= 50; if (power <= 0) { dead(); GamePanel.burst = new Burst(x, y); } return true; } } //...... //此处省略与其他角色碰撞的逻辑,比如boss等 //...... return false; }
3.Hero 子弹
public class Hero extends Role { //xy上的移动速度(带方向) protected float vx; protected float vy; public void move() { //先移动 x += vx; y += vy; //如果移出屏幕,则死亡,一般是子弹这类 if (x + WIDTH < 0.0F || x > (float) app.getWidth() || y + HEIGHT < 0.0F || y > (float) app.getHeight()) dead(); } }
Hero
|----BattleShot 玩家子弹
| |----BattleBasic 普通子弹
| |----BattleBeam 激光
|----EnemyShot 敌人子弹
|----CircleBullets 圆圈子弹
|----MoveAimingBullet 向玩家发射的子弹
|----......
4. 入口点 Main
public class Main { public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new STGFrame(); } }); } }
STGFrame代码省略,就是嵌套一个GamePanel
5.GamePanel (骨架代码)
这个是整个飞机游戏的核心代码。
public class GamePanel extends Panel implements Runnable { //游戏核心线程 private Thread gameThread; //模式 public static int gameMode; //后台Image(目的是缓冲,防画面闪烁) private Image offImage; //后台Graphics private Graphics g_off; //玩家飞机 public static Image heroImage; //所有角色列表 public static LinkedList<Role> list; //临时角色列表 public static LinkedList<Role> listTmp; //玩家 Battle battle; }
5.1 初始化
public GamePanel() { list = new LinkedList<Role>(); listTmp = new LinkedList<Role>(); //载入所有图片 heroImage = Utility.loadImage("image/this.gif"); enemyImageA = Utility.loadImage("image/enemyA.gif"); //...... //此处省略其他图片 //...... gameMode = 0; //焦点聚焦,接收键盘输入 addKeyListener(new Key()); setFocusable(true); requestFocus(); setBackground(Color.black); setForeground(Color.white); //启动核心线程 gameThread = new Thread(this); gameThread.start(); }
5.2 核心线程
public void run() { while (gameThread == Thread.currentThread()) { //绘制打底图 gameRender(); if (g_off != null) { long RefreshTime = System.currentTimeMillis(); try { Thread.sleep(2L); } catch (InterruptedException e) { } switch (gameMode) { case 0: title(); break; case 1: stage1(); break; case 12: ready(); break; //...... //此处省略其他模式 //...... } //前面都是在内存中画,现在一次性画到屏幕上 paintScreen(); //以下防止电脑太快,适当的休息一下(其实是空转cpu,不太好) while (System.currentTimeMillis() - RefreshTime < 13L) ; } } }
可以看到核心线程就是一个死循环,根据不同的模式执行不同的逻辑。
模式表
编号 | 方法 | 含义 |
0 | title | 标题画面 |
1 | stage1 | 第1关 |
2 | stage2 | 第2关 |
3 | stage3 | 第3关 |
10 | congratulation | 恭喜画面 |
11 | gameOver | 游戏结束画面 |
12 | ready | 准备阶段 |
13 | appearingAnime | 玩家飞机登场画面 |
14 | crear | 打败boss阶段 |
15 | disappearing | 关卡通关画面 |
16 | bossDeathAnime | boss死亡画面 |
然后关键就是用双缓冲技术画图,防止屏幕闪烁。
private void gameRender() { if (offImage == null) { offImage = createImage(450, 500); if (offImage == null) return; g_off = offImage.getGraphics(); } g_off.setColor(Color.BLACK); g_off.fillRect(0, 0, 450, 500); } public void paintScreen() { try { Graphics g = getGraphics(); if (g != null && offImage != null) g.drawImage(offImage, 0, 0, null); Toolkit.getDefaultToolkit().sync(); if (g != null) g.dispose(); } catch (Exception e) { e.printStackTrace(); } }
5.3 主程序
看一下stage1里面调用主程序gameMain
private void stage1() { StageA.start(); gameMain(); } private void gameMain() { //角色碰撞检测,注意这里很通用,不论玩家飞机还是敌机都存在于这个list中,等待碰撞检测 for (int i = 0; i < list.size(); i++) { Role chara1 = list.get(i); for (int j = 0; j < list.size(); j++) { //2重嵌套循环,判断角色之间的两两碰撞,性能会受影响,可考虑《算法第四版》一书中的碰撞检测算法来优化 Role chara2 = list.get(j); chara1.checkHit(chara2); } } //移动角色,并绘画 for (int i = list.size() - 1; i >= 0; i--) { Role chara1 = (Role) list.get(i); chara1.move(); chara1.draw(g_off); } //listTmp加入list for (int i = 0; i < listTmp.size(); i++) list.add(listTmp.get(i)); //玩家如果死亡,进入11模式 if (battle.isDead()) { gameMode = 11; } listTmp.clear(); }
这里的碰撞检测便是关键了,2重嵌套循环,判断角色之间的两两碰撞。接下来每个角色移动。
可以说它便是许多游戏实现的关键所在。有了这个骨架代码,只要实现不同Role的checkHit和move还有draw方法就可以了,游戏的扩展性变得简单。
6. EnemyTable 敌人登场表
敌人什么时候出现,为了避免硬编码,于是定了一张表格,这个便是表格类。
public class EnemyTable { //登场时间 public int time; //登场xy public float x; public float y; //种类(0,1,2,3,4) public int enemyKind; //形式 public int pattern; }
7. 关卡设计
public class StageA { //依次出现:(时间以50为单位) //2个A,2个A,6个A+1个C static EnemyTable stageA[] = { new EnemyTable(0, 0, 25F, -50F, 0), new EnemyTable(0, 0, 250F, -50F, 1), new EnemyTable(0, 1, 25F, -50F, 0), new EnemyTable(0, 1, 300F, -50F, 1), new EnemyTable(0, 2, 30F, -50F, 0), new EnemyTable(0, 2, 20F, -50F, 2), new EnemyTable(0, 2, 100F, -50F, 2), new EnemyTable(0, 2, 200F, -50F, 2), new EnemyTable(0, 2, 300F, -50F, 2), new EnemyTable(0, 2, 330F, -50F, 1), new EnemyTable(2, 2, 20F, -50F, 0), //............ }; public static void start() { for (int i = 0; i < stageA.length; i++) { //如果时间到了(以50为单位),则敌人登场 if ((double) stageA[i].time == (double) GamePanel.time / 50D) if (stageA[i].enemyKind == 0) GamePanel.addList(new EnemyA(stageA[i].x, stageA[i].y, _battle, stageA[i].pattern)); else if (stageA[i].enemyKind == 1) GamePanel.addList(new EnemyB(stageA[i].x, stageA[i].y, _battle, stageA[i].pattern)); //............ } } }
看到了吗,这样改关卡就变得容易多了,只要改最上面那个表格就ok了。其实做的更好的话可以提取到一个配置文件里。
8.各种敌人,子弹的设计
接下来就是开动你的想象力的时间了。结合各种数学,物理知识,做出千变万化的角色。
这里分析几个例子
8.1 EnemyA
public class EnemyA extends Enemy { public void move() { //............ } else if (pattern == 2) { //sin函数可以展现弧线的运动轨迹 x += Math.sin((3.1415926535897931D * (double) counter) / 40D) * 5D; y += 1.5D; } else if (pattern == 3) { //转圈 if (counter < 50) y += 2.5D; else if (counter >= 100) { x += Math.sin((3.1415926535897931D * ((double) counter - 100D)) / 160D) * 2.5D; y += Mathh.sin((3.1415926535897931D * ((double) counter - 20D)) / 160D) * 2.5D; } } }
下图分别是pattern 2 和pattern 3的运行轨迹,可以看到pattern2使用一个sin函数可以展现弧线的运动轨迹。而pattern3使用2个sin函数可以让敌机转圈。
8.2 MoveAimingBullet
这个类不错,敌人会朝着玩家发射出子弹,而不是乱放空枪,使得敌人少许有了一些AI。
public MoveAimingBullet(float x, float y, Battle ziki) { super(x, y); speed = 2.0F; x_ziki = ziki.x; y_ziki = ziki.y; x_enemy = x; y_enemy = y; distance = (float) Math .sqrt((((double) x_ziki + (double) ziki.WIDTH / 2D) - (double) x_enemy) * (((double) x_ziki + (double) ziki.WIDTH / 2D) - (double) x_enemy) + (double) ((y_ziki - y_enemy) * (y_ziki - y_enemy))); if (distance != 0.0F) { vx = (float) (((((double) x_ziki + (double) ziki.WIDTH / 2D) - (double) x_enemy) / (double) distance) * (double) speed); vy = ((y_ziki - y_enemy) / distance) * speed; } else { vx = 0.0F; vy = speed; } }
如图,数学公式就是先算出敌我之间的距离,distance=sqrt(x^2+y^2)
然后放出的子弹的速度就是
vx=x/distance
vy=y/distance
8.3 CircleBullets
老版更厉害,可以放出一个圆圈的子弹。
public CircleBullets(float x, float y, boolean flag) { super(x, y); speed = 1.0F; //老版一次放24枚子弹 tamaNum = 24; vxCircle = new float[tamaNum]; vyCircle = new float[tamaNum]; float rad_step = (float) (6.2831853071795862D / (double) tamaNum); float rad; if (flag) rad = 0.0F; else rad = (float) ((double) rad_step / 2D); for (int i = 0; i < tamaNum;) { vxCircle[i] = (float) (Math.cos(rad) * (double) speed); vyCircle[i] = (float) (Math.sin(rad) * (double) speed); GamePanel.addList(new EnemyShot(x, y, vxCircle[i], vyCircle[i])); i++; rad += rad_step; } vx = vxCircle[0]; vy = vyCircle[0]; }
9.总结
可以看到,用java做游戏并不难。这个例子可以作为新手做STG游戏(飞机大战,坦克大战)的一个起步。
当然这个例子是纯java,没有用任何框架。当代码膨胀了以后,可以考虑用一些游戏框架来解放我们的生产力。
另外,原作者cping1982的博客相当好,有许多java游戏编程的资料值得参考。
发表评论
-
Java版赤色要塞源码分析
2015-01-17 17:12 24381.框架与环境搭建 1.1 本游戏使用了以下框架 slick2 ... -
Java版赤色要塞
2015-01-15 13:44 1708老外居然用Java复刻了一个赤色要塞! 出处:http://m ... -
Escape the men's room(Java版密室逃脱)
2015-01-13 23:48 19371.概述 老外用Java做的2D密室逃脱游戏。个人认为挺不错的 ... -
freetts程序示例:报时程序和伪人机对话
2015-01-11 21:52 41300.概述 语音合成,是将人类语音用人工的方式所产生。若 ... -
Java2D API视觉特效
2015-01-07 21:40 10731.一个不错的例子 Killer Game Programmi ... -
魍魉校园(Java版AVG游戏开发入门)源码分析
2014-12-29 21:19 13860.前言 本例子取自cping19 ... -
java播放mp3/ogg/ape/flac音乐
2014-12-29 16:19 15827好吧,又要说一句了,java真是无所不能。 用java sou ... -
使用jfugue来演奏mid音乐
2014-12-26 17:21 1870java真是无所不能,居然 ...
相关推荐
《Java仿雷电(雷霆行动)及其源代码》是一款基于Java编程语言开发的STG(Shoot Them Up,射击类)游戏,旨在模仿经典的雷电系列。这款游戏由GreenJVM发布,一个专门针对Java应用程序优化的运行环境,允许游戏在没有...
4. 游戏存档:游戏可能使用STG文件保存进度和用户数据。 总的来说,STG文件是信息技术领域中一个重要的数据存储解决方案,其灵活性和适应性使其在各种场景下都有所应用。理解和掌握如何操作STG文件,对于提升工作...
标题中的“STG检测路由器流量”指的是一个专门用于监控路由器网络流量的工具或软件,它采用了SNMP(Simple Network Management Protocol)协议来收集和分析数据。SNMP是一种广泛应用于网络设备管理的标准协议,允许...
STG(Shoot Them Up)是一种深受玩家喜爱的游戏类型,通常涉及空中战斗和射击元素。而“跨平台STG游戏引擎”则是专为开发这类游戏设计的软件工具,它允许开发者在多个操作系统上构建和运行STG游戏,如Windows、MacOS...
STG (SNMP Traffic Grapher) version 1.4.5 Copyright (C) 2000 Leonid Mikhailov This freeware utility allows monitoring of supporting SNMPv1 and SNMPv2c devices including Cisco, Livingstone, River...
在“uC_OC_II.rar_OC STG_uc oc源码”这个压缩包中,包含了uC/OS-II的源代码,这对于开发者来说是一份极其宝贵的资源,能够深入理解其工作原理并进行定制化开发。 1. **uC/OS-II核心概念** - **任务(Task)**:uC...
该项目为Java语言编写的游戏后台服务端设计源码,包含48个文件,其中包括32个Java源文件、7个属性文件、3个偏好设置文件以及少量其他类型文件。该系统专注于提供高效稳定的服务端支持,适用于游戏开发场景。
高分项目,基于Unity3D开发实现的官方超好画质的射击游戏源码,内含完整源码+资源+unitypackage 射击游戏(Shooting game),简称为STG。游戏类型的一种,也是动作游戏的一种。射击游戏带有很明显的动作游戏特点,也没有...
一个由“几何战争”作者开发的STG游戏,躲避子弹然后按Z反击:) 压缩包中包括源码和编译好的swf文件,自己试试吧! (上下左右控制方向,按着Z不放是向前方发出子弹) Control your ship Arrow keys Fire a glider ...
STG719是一款高速S.P.D.T. (单刀双掷)SWITCH采用硅栅C2MOS技术制造。 它的设计工作电压为1.8V至5.5V,非常适合便携式应用,音频信号路由,视频切换,移动和通信系统。 它在5V 25°C时提供4Ω导通电阻Max,并具有极...
在Android平台上开发游戏,尤其是飞行射击类(STG,Shoot 'em up)游戏,涉及到许多技术点和步骤。本文将详细解析"android 飞机游戏"这一项目,包括其核心概念、关键技术以及可能遇到的问题。 一、Android游戏开发...
STG(Shoot 'em up),又称射击游戏,是一种快节奏的动作游戏类型,玩家通常需要控制飞行器或角色躲避敌人的攻击并反击。在STG游戏中,"环形子弹"是一种常见的设计元素,它增加了游戏的视觉效果和挑战性。 J2ME中的...
高分项目,基于Unity3D开发实现的射击游戏Flip The Gun,内含完整源码+资源 射击游戏(Shooting game),简称为STG。游戏类型的一种,也是动作游戏的一种。射击游戏带有很明显的动作游戏特点,也没有纯然的射击游戏,因为...
[Rocky Nook] 改进测试进程 (Stg 版本) (英文版) [Rocky Nook] Improving the Test Process Stg Edition (E-Book) ☆ 图书概要:☆ This book covers the syllabus for the Improving the Test Process module of...
《PlanetBuster3:弹幕STG游戏》是一款基于JavaScript技术开发的射击类游戏,具有高速、华丽的弹幕效果,为玩家带来刺激的空战体验。在这款游戏中,玩家将扮演一位勇猛的飞行员,驾驶飞船穿越密集的弹幕,击败强大的...
Test STG4是一个用于iOS和macOS的实验性地狱引擎,用于创建东方风格的游戏 该引擎是和 建造 这只是一个Xcode项目。 建立在Big Sur 11.2.1和Xcode 12.2之上 特征 标有NEW的功能是TestSTG系列的新功能 iOS和macOS支持...
在开始游戏后,场景中央的boss将开始发射弹幕。 使用方向键操控玩家躲避子弹。 按下shift键将能够进入低速模式,能以更高精度移动,并将显示判定点。 游戏时间持续90秒,游戏将记录您的中弹次数 当90秒结束后,游戏...
高分项目,基于Unity3D开发实现的Advance Sniper Starter Kit 射击游戏源码,内含完整源码+资源+unitypackage 射击游戏(Shooting game),简称为STG。游戏类型的一种,也是动作游戏的一种。射击游戏带有很明显的动作...
本教程通过一个名为"stg.rar"的压缩包,提供了一个关于如何使用VC++(Visual C++)进行Direct Draw编程的实例,特别是针对游戏编程的入门学习。 在Direct Draw编程中,有几个关键概念和步骤是必不可少的: 1. **...