flappy bird电脑版bird中的评价函数是怎么设计的

前言2013年DeepMind 在NIPS上发表Playing Atari with Deep Reinforcement Learning 一文,提出了DQN(Deep Q Network)算法,实现端到端学习玩Atari游戏,即只有像素输入,看着屏幕玩游戏。Deep Mind就凭借这个应用以6亿美元被Google收购。由于DQN的开源,在github上涌现了大量各种版本的DQN程序。但大多是复现Atari的游戏,代码量很大,也不好理解。Flappy Bird是个极其简单又困难的游戏,风靡一时。在很早之前,就有人使用Q-Learning 算法来实现完Flappy Bird。 但是这个的实现是通过获取小鸟的具体位置信息来实现的。能否使用DQN来实现通过屏幕学习玩Flappy Bird是一个有意思的挑战。(话说本人和朋友在去年年底也考虑了这个idea,但当时由于不知道如何截取游戏屏幕只能使用具体位置来学习,不过其实也成功了)最近,github上有人放出使用DQN玩Flappy Bird的代码,【1】 该repo通过结合之前的repo成功实现了这个想法。这个repo对整个实现过程进行了较详细的分析,但是由于其DQN算法的代码基本采用别人的repo,代码较为混乱,不易理解。
为此,本人改写了一个版本对DQN代码进行了重新改写。本质上对其做了类的封装,从而使代码更具通用性。可以方便移植到其他应用。当然,本文的目的是借Flappy Bird DQN这个代码来详细分析一下DQN算法极其使用。DQN 伪代码这个是NIPS13版本的伪代码:[code]Initialize replay memory D to size N
Initialize action-value function Q with random weights
for episode = 1, M do
Initialize state s_1
for t = 1, T do
With probability ? select random action a_t
otherwise select a_t=max_a
Q($s_t$,a; $θ_i$)
Execute action a_t in emulator and observe r_t and s_(t+1)
Store transition (s_t,a_t,r_t,s_(t+1)) in D
Sample a minibatch of transitions (s_j,a_j,r_j,s_(j+1)) from D
r_j for terminal s_(j+1)
r_j+γ*max_(a^' )
Q(s_(j+1),a'; θ_i) for non-terminal s_(j+1)
Perform a gradient step on (y_j-Q(s_j,a_j; θ_i))^2 with respect to θ
end for基本的分析详见 基础知识详见本文主要从代码实现的角度来分析如何编写Flappy Bird DQN的代码编写FlappyBirdDQN.py首先,FlappyBird的游戏已经编写好,是现成的。提供了很简单的接口:[code]nextObservation,reward,terminal = game.frame_step(action)即输入动作,输出执行完动作的屏幕截图,得到的反馈reward,以及游戏是否结束。那么,现在先把DQN想象为一个大脑,这里我们也用BrainDQN类来表示,这个类只需获取感知信息也就是上面说的观察(截图),反馈以及是否结束,然后输出动作即可。完美的代码封装应该是这样。具体DQN里面如何存储。如何训练是外部不关心的。 因此,我们的FlappyBirdDQN代码只有如下这么短:[code]# -------------------------
# Project: Deep Q-Learning on Flappy Bird
# Author: Flood Sung
# -------------------------
import cv2
import sys
sys.path.append("game/")
import wrapped_flappy_bird as game
from BrainDQN import BrainDQN
import numpy as np
# preprocess raw image to 80*80 gray image
def preprocess(observation):
observation = cv2.cvtColor(cv2.resize(observation, (80, 80)), cv2.COLOR_BGR2GRAY)
ret, observation = cv2.threshold(observation,1,255,cv2.THRESH_BINARY)
return np.reshape(observation,(80,80,1))
def playFlappyBird():
# Step 1: init BrainDQN
brain = BrainDQN()
# Step 2: init Flappy Bird Game
flappyBird = game.GameState()
# Step 3: play game
# Step 3.1: obtain init state
action0 = np.array([1,0])
# do nothing
observation0, reward0, terminal = flappyBird.frame_step(action0)
observation0 = cv2.cvtColor(cv2.resize(observation0, (80, 80)), cv2.COLOR_BGR2GRAY)
ret, observation0 = cv2.threshold(observation0,1,255,cv2.THRESH_BINARY)
brain.setInitState(observation0)
# Step 3.2: run the game
while 1!= 0:
action = brain.getAction()
nextObservation,reward,terminal = flappyBird.frame_step(action)
nextObservation = preprocess(nextObservation)
brain.setPerception(nextObservation,action,reward,terminal)
def main():
playFlappyBird()
if __name__ == '__main__':
main()核心部分就在while循环里面,由于要讲图像转换为80x80的灰度图,因此,加了一个preprocess预处理函数。这里,显然只有有游戏引擎,换一个游戏是一样的写法,非常方便。接下来就是编写BrainDQN.py 我们的游戏大脑编写BrainDQN基本架构:[code]class BrainDQN:
def __init__(self):
# init replay memory
self.replayMemory = deque()
# init Q network
self.createQNetwork()
def createQNetwork(self):
def trainQNetwork(self):
def setPerception(self,nextObservation,action,reward,terminal):
def getAction(self):
def setInitState(self,observation):基本的架构也就只需要上面这几个函数,其他的都是多余了,接下来就是编写每一部分的代码。CNN代码也就是createQNetwork部分,这里采用如下图的结构(转自【1】): 这里就不讲解整个流程了。主要是针对具体的输入类型和输出设计卷积和全连接层。代码如下:[code]
def createQNetwork(self):
# network weights
W_conv1 = self.weight_variable([8,8,4,32])
b_conv1 = self.bias_variable([32])
W_conv2 = self.weight_variable([4,4,32,64])
b_conv2 = self.bias_variable([64])
W_conv3 = self.weight_variable([3,3,64,64])
b_conv3 = self.bias_variable([64])
W_fc1 = self.weight_variable([])
b_fc1 = self.bias_variable([512])
W_fc2 = self.weight_variable([512,self.ACTION])
b_fc2 = self.bias_variable([self.ACTION])
# input layer
self.stateInput = tf.placeholder("float",[None,80,80,4])
# hidden layers
h_conv1 = tf.nn.relu(self.conv2d(self.stateInput,W_conv1,4) + b_conv1)
h_pool1 = self.max_pool_2x2(h_conv1)
h_conv2 = tf.nn.relu(self.conv2d(h_pool1,W_conv2,2) + b_conv2)
h_conv3 = tf.nn.relu(self.conv2d(h_conv2,W_conv3,1) + b_conv3)
h_conv3_flat = tf.reshape(h_conv3,[-1,1600])
h_fc1 = tf.nn.relu(tf.matmul(h_conv3_flat,W_fc1) + b_fc1)
# Q Value layer
self.QValue = tf.matmul(h_fc1,W_fc2) + b_fc2
self.actionInput = tf.placeholder("float",[None,self.ACTION])
self.yInput = tf.placeholder("float", [None])
Q_action = tf.reduce_sum(tf.mul(self.QValue, self.actionInput), reduction_indices = 1)
self.cost = tf.reduce_mean(tf.square(self.yInput - Q_action))
self.trainStep = tf.train.AdamOptimizer(1e-6).minimize(self.cost)记住输出是Q值,关键要计算出cost,里面关键是计算Q_action的值,即该state和action下的Q值。由于actionInput是one hot vector的形式,因此tf.mul(self.QValue, self.actionInput)正好就是该action下的Q值。training 部分。这部分是代码的关键部分,主要是要计算y值,也就是target Q值。[code]
def trainQNetwork(self):
# Step 1: obtain random minibatch from replay memory
minibatch = random.sample(self.replayMemory,self.BATCH_SIZE)
state_batch = [data[0] for data in minibatch]
action_batch = [data[1] for data in minibatch]
reward_batch = [data[2] for data in minibatch]
nextState_batch = [data[3] for data in minibatch]
# Step 2: calculate y
y_batch = []
QValue_batch = self.QValue.eval(feed_dict={self.stateInput:nextState_batch})
for i in range(0,self.BATCH_SIZE):
terminal = minibatch[i][4]
if terminal:
y_batch.append(reward_batch[i])
y_batch.append(reward_batch[i] + GAMMA * np.max(QValue_batch[i]))
self.trainStep.run(feed_dict={
self.yInput : y_batch,
self.actionInput : action_batch,
self.stateInput : state_batch
})其他部分其他部分就比较容易了,这里直接贴出完整的代码:[code]# -----------------------------
# File: Deep Q-Learning Algorithm
# Author: Flood Sung
# -----------------------------
import tensorflow as tf
import numpy as np
import random
from collections import deque
class BrainDQN:
# Hyper Parameters:
ACTION = 2
FRAME_PER_ACTION = 1
GAMMA = 0.99 # decay rate of past observations
OBSERVE = 100000. # timesteps to observe before training
EXPLORE = 150000. # frames over which to anneal epsilon
FINAL_EPSILON = 0.0 # final value of epsilon
INITIAL_EPSILON = 0.0 # starting value of epsilon
REPLAY_MEMORY = 50000 # number of previous transitions to remember
BATCH_SIZE = 32 # size of minibatch
def __init__(self):
# init replay memory
self.replayMemory = deque()
# init Q network
self.createQNetwork()
# init some parameters
self.timeStep = 0
self.epsilon = self.INITIAL_EPSILON
def createQNetwork(self):
# network weights
W_conv1 = self.weight_variable([8,8,4,32])
b_conv1 = self.bias_variable([32])
W_conv2 = self.weight_variable([4,4,32,64])
b_conv2 = self.bias_variable([64])
W_conv3 = self.weight_variable([3,3,64,64])
b_conv3 = self.bias_variable([64])
W_fc1 = self.weight_variable([])
b_fc1 = self.bias_variable([512])
W_fc2 = self.weight_variable([512,self.ACTION])
b_fc2 = self.bias_variable([self.ACTION])
# input layer
self.stateInput = tf.placeholder("float",[None,80,80,4])
# hidden layers
h_conv1 = tf.nn.relu(self.conv2d(self.stateInput,W_conv1,4) + b_conv1)
h_pool1 = self.max_pool_2x2(h_conv1)
h_conv2 = tf.nn.relu(self.conv2d(h_pool1,W_conv2,2) + b_conv2)
h_conv3 = tf.nn.relu(self.conv2d(h_conv2,W_conv3,1) + b_conv3)
h_conv3_flat = tf.reshape(h_conv3,[-1,1600])
h_fc1 = tf.nn.relu(tf.matmul(h_conv3_flat,W_fc1) + b_fc1)
# Q Value layer
self.QValue = tf.matmul(h_fc1,W_fc2) + b_fc2
self.actionInput = tf.placeholder("float",[None,self.ACTION])
self.yInput = tf.placeholder("float", [None])
Q_action = tf.reduce_sum(tf.mul(self.QValue, self.actionInput), reduction_indices = 1)
self.cost = tf.reduce_mean(tf.square(self.yInput - Q_action))
self.trainStep = tf.train.AdamOptimizer(1e-6).minimize(self.cost)
# saving and loading networks
saver = tf.train.Saver()
self.session = tf.InteractiveSession()
self.session.run(tf.initialize_all_variables())
checkpoint = tf.train.get_checkpoint_state("saved_networks")
if checkpoint and checkpoint.model_checkpoint_path:
saver.restore(self.session, checkpoint.model_checkpoint_path)
print "Successfully loaded:", checkpoint.model_checkpoint_path
print "Could not find old network weights"
def trainQNetwork(self):
# Step 1: obtain random minibatch from replay memory
minibatch = random.sample(self.replayMemory,self.BATCH_SIZE)
state_batch = [data[0] for data in minibatch]
action_batch = [data[1] for data in minibatch]
reward_batch = [data[2] for data in minibatch]
nextState_batch = [data[3] for data in minibatch]
# Step 2: calculate y
y_batch = []
QValue_batch = self.QValue.eval(feed_dict={self.stateInput:nextState_batch})
for i in range(0,self.BATCH_SIZE):
terminal = minibatch[i][4]
if terminal:
y_batch.append(reward_batch[i])
y_batch.append(reward_batch[i] + GAMMA * np.max(QValue_batch[i]))
self.trainStep.run(feed_dict={
self.yInput : y_batch,
self.actionInput : action_batch,
self.stateInput : state_batch
# save network every 100000 iteration
if self.timeStep % 10000 == 0:
saver.save(self.session, 'saved_networks/' + 'network' + '-dqn', global_step = self.timeStep)
def setPerception(self,nextObservation,action,reward,terminal):
newState = np.append(nextObservation,self.currentState[:,:,1:],axis = 2)
self.replayMemory.append((self.currentState,action,reward,newState,terminal))
if len(self.replayMemory) & self.REPLAY_MEMORY:
self.replayMemory.popleft()
if self.timeStep & self.OBSERVE:
# Train the network
self.trainQNetwork()
self.currentState = newState
self.timeStep += 1
def getAction(self):
QValue = self.QValue.eval(feed_dict= {self.stateInput:[self.currentState]})[0]
action = np.zeros(self.ACTION)
action_index = 0
if self.timeStep % self.FRAME_PER_ACTION == 0:
if random.random() &= self.epsilon:
action_index = random.randrange(self.ACTION)
action[action_index] = 1
action_index = np.argmax(QValue)
action[action_index] = 1
action[0] = 1 # do nothing
# change episilon
if self.epsilon & self.FINAL_EPSILON and self.timeStep & self.OBSERVE:
self.epsilon -= (self.INITIAL_EPSILON - self.FINAL_EPSILON)/self.EXPLORE
return action
def setInitState(self,observation):
self.currentState = np.stack((observation, observation, observation, observation), axis = 2)
def weight_variable(self,shape):
initial = tf.truncated_normal(shape, stddev = 0.01)
return tf.Variable(initial)
def bias_variable(self,shape):
initial = tf.constant(0.01, shape = shape)
return tf.Variable(initial)
def conv2d(self,x, W, stride):
return tf.nn.conv2d(x, W, strides = [1, stride, stride, 1], padding = "SAME")
def max_pool_2x2(self,x):
return tf.nn.max_pool(x, ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = "SAME")一共也只有160代码。 如果这个任务不使用深度学习,而是人工的从图像中找到小鸟,然后计算小鸟的轨迹,然后计算出应该怎么按键,那么代码没有好几千行是不可能的。深度学习大大减少了代码工作。小结本文从代码角度对于DQN做了一定的分析,对于DQN的应用,大家可以在此基础上做各种尝试。
如果您想留下此文,您可以将其发送至您的邮箱(将同时以邮件内容&PDF形式发送)
相关文章推荐
(Ctrl+Enter提交) &&
已有0人在此发表见解
&在& 00:11收藏到了
&&在信息爆炸的时代,您的知识需要整理,沉淀,积累!Lai18为您提供一个简单实用的文章整理收藏工具,在这里您可以收藏对您有用的技术文章,自由分门别类,在整理的过程中,用心梳理自己的知识!相信,用不了多久,您收藏整理的文章将是您一生的知识宝库!
· 蜀ICP备号-1【Unity】FlappyBird剖析-附源码
时间: 14:53:31
&&&& 阅读:215
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&FlappyBird不用多说了,一款极其简单,但是又很火的游戏。我在得知这款疯狂的游戏后,就有一种把它重现的冲动,然后花了我4个多小时,产生出了一个可以玩的版本,分享给大家(文末尾付下载链接)。
下面简单介绍游戏的开发过程(本文的例子需要使用unity4.3.0以上的版本打开)。
项目的目录结构如下图,anims中存放动画资源,prefab中存放预置对象,scprits存放脚本,sprites用来存放贴图。
获取FlappyBird的贴图资源和音效资源。把资源导入到sprites文件夹下,选中atlas,在Inspector中进行编辑,如下图:
设置为sprite,模式为Multiple,点击按钮Sprite Editor进行相应的图片分隔。在弹出的对话框中,可以使用自动切图方式,如下图:
接下来就可以进行编码了
为了区分场景的层次(主要是用来决定图层的顺序,sorting Layer的功能)以及编码的需求,建立一些tag sorting Layer和Layer。先点击Unity编辑器右上方的Layers下拉菜单并选择&Edit Layers...&,如下图:
并填写如下信息:
移动的道路和障碍
一格道路有两个障碍(如下图),场景中用两格道路来反复循环(当一格道路移出屏幕后就重新调整位置,等待下一次出现在屏幕上),达到不断移动的效果。
下面是道路移动的部分代码road.cs
public class road : MonoBehaviour {
// Update is called once per frame
void Update () {
Vector3 pos = trans.
pos.x -= speed * Time.deltaT
trans.position =
if(pos.x &= -1.6f - 3.35f*idx) {
//当道路移出屏幕后,从小调整其位置
Vector3 pp = roads[idx%2].transform.
pp.x += 3.35f;
roads[idx%2].transform.position =
if(isBegin){
roads[idx%2].GetComponent&roadGen&().gen();
道路障碍的显示与否(在欢迎页面,路面不需要障碍),以及障碍的生成都在文件roadGen.cs中,我把上下柱子合并成一个对象,在生成障碍时,只要使其在一定范围内上下移动就可以了。代码片段如下:
public class roadGen : MonoBehaviour {
public GameObject[]
public float down=3.8f, upper = 6.0f;
public void gen() { // 一格道路有两个柱子
zhuzi[0].SetActive(true);
zhuzi[1].SetActive(true);
Vector3 p = zhuzi[0].transform.localP
float vv = Random.
p.y = Mathf.Lerp(down, upper, vv);
zhuzi[0].transform.localPosition = //设置第一个柱子的位置
p = zhuzi[1].transform.localP
vv = Random.
p.y = Mathf.Lerp(down, upper, vv);
zhuzi[1].transform.localPosition = //设置第二个柱子的位置
public void hidden() {
zhuzi[0].SetActive(false);
zhuzi[1].SetActive(false);
最后在障碍物和地面都添加BoxCollider2D,使其能够获取碰撞消息。
大嘴唇的小鸟
首先小鸟有个飞行的帧动画,在sprite文件夹下的atlas中,选择三个帧,直接拖动到场景中,unity自动形成了一个带有帧动画的sprite。选中该sprite,在Window/Animation界面中,调整sprite的播放时间,如下图:
同样要给小鸟一个BoxCollider2D的Component,使其能够响应碰撞,还要添加Rigibody2D。具体请参考例子。这里会涉及到两个脚本(时间匆忙,没怎么考虑设计):bird.cs和clider.cs;前者用来向小鸟施加力的作用,后者处理碰撞。
这个游戏的最主要部分就是 clider .cs,这个文件处理得分和是否碰撞到障碍物。代码如下:
using UnityE
using System.C
public class clider : MonoBehaviour {
public int clideN
public bool isSuccess = false, isFail =
// Use this for initialization
void Start () {
s = GameObject.Find(&score&).GetComponent&score&();
clideNum = 0;
isSuccess =
// Update is called once per frame
void Update () {
void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.tag.Equals(&success&)) {
if(!isSuccess) {
print(&===trigger enter==&);
isSuccess =
s.success();
print (&success&);
} else if(!isFail) {
print(&===trigger enter==&);
print (&fail&);
void OnTriggerExit2D(Collider2D other) {
print(&===trigger exit==&);
isSuccess =
void OnCollisionEnter2D(Collision2D other) {
if(other.gameObject.tag.Equals(&success&)) {
if(!isSuccess) {
print(&===collision enter==&);
isSuccess =
s.success();
} else if(!isFail) {
print(&===collision enter==&);
void OnCollisionExit2D(Collision2D coll) {
print(&===collision exit==&);
isSuccess =
public void reset() {
isSuccess =
欢迎页面有个小鸟的动画,并且能够响应触摸后开始游戏(在isReady.cs中实现)。
小鸟的动画就是上下摆动的过程,选择小鸟,然后在Animation界面中,添加Position属性,并调节如下图:
isReady.cs的代码如下:
public class isReady : MonoBehaviour {
public GameObject road,
// Use this for initialization
void Start () {
// Update is called once per frame
void Update () {
if(Input.GetButtonDown(&Fire1&)){ //用户触摸屏幕之后,就开始游戏了
gameObject.SetActive(false);
road.GetComponent&road&().isBegin =
bird.GetComponent&Rigidbody2D&().isKinematic =//欢迎页面,这里设置为true,使小鸟不响应重力,开始后要设置为false
bird.GetComponent&Animator&().enabled =
结算页面开始使隐藏的,等用户输了之后,就会播放一个动画并显示,当用户点击play按钮后,游戏重置到欢迎页面。结算页面涉及到了脚本restart.cs
这里游戏重置的时,用到了BroadcastMessage的技术,即查找所有tag为needReset的对象,并调用其自身以及子对象中的代码中的reset函数来进行游戏的重置。代码如下:
public class restart : MonoBehaviour {
public Camera cam2d;
public GameO
void Update () {
if(Input.GetButtonDown(&Fire1&)){
Collider2D h = Physics2D.OverlapPoint(cam2d.ScreenToWorldPoint(Input.mousePosition), (1&&LayerMask.NameToLayer(&btn&)));
// 如果点击play按钮
gameObject.SetActive(false);
Time.timeScale = 1;
ready.SetActive(true);
GameObject[] resets = GameObject.FindGameObjectsWithTag(&needReset&); //查找所有tag为needReset的对象
foreach(GameObject r in resets) {
r.BroadcastMessage(&reset&); //调用其自身以及子对象中的代码中的reset函数来进行游戏的重置
关于Physics2D.OverlapPoint的用法,请参考《【》中的第二点。
声明:这篇文章中所引用的资源部分来自网络,仅供学习之用,请勿商业化。
下载地址:
apk下载链接:标签:&&&&&&&&&&&&&&&原文:http://blog.csdn.net/stalendp/article/details/
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!二维游戏设计与制作精品资源共享课程
此页面上的内容需要较新版本的 Adobe Flash Player。
资源特色 当前位置: & 基本资源清单
基本资源清单
资源介绍(列表)
包含课程目标、课程性质与定位、专业/岗位要求及人才培养目标、课程设计思路、学习情境设计(高职专用)、与前后课程关系、课程特色、教学条件等。其中,教学条件要包括对执教教师的要求,对学习场地、教学设施设备、教学材料、实验实训设备等的要求。并包括获评精品课程后的教学沿革(团队变迁、学科班级情况、教学效果)
包括有课程目标、内容目标、实施建议等,在课程的基本理念、课程目标、课程实施建议等几部分阐述的详细、明确,特别是提出了面向全体学生的学习基本要求。
包括课程的教学目的、教学任务、教学内容的结构、模块或单元教学目标与任务、教学活动以及教学方法上的基本要求等。
包含了课程实验教学环节的目的,任务和内容,给主讲教师进行实验教学提供指导
包括了课程考核的相关规定,有课程考核的目标、内容、考核模块如形成性考核和终结性考核直接的比例和内容
包含了课程实训教学环节的目的,任务和内容,给主讲教师进行实训教学提供指导
包含了课程实训阶段的目的、任务、步骤、操作流程、评价体会、总结分析内容,是学生进行实训项目开展的依据和指导材料
教学日历是教师组织教学的实施计划表,包括具体教学进程、授课内容及时间、课外作业、授课方式等
给予学生以课程导学,是对学生学好本门课程的建议与指导
ActionScript2.0基础知识
Flash网页游戏、手机游戏的发展;Flash游戏的制作流程;ActionScript编程基础;事件和事件处理的使用;常用内置类
ActionScript2.0游戏实例制作
甜品师学习之旅游戏;小鸟出窝游戏
ActionScript3.0基础知识
包和命名空间的概念;使用FlashDevelop编辑AS文件;应用函数;ActionScript3.0事件处理;创建ActionScript3.0游戏框架
ActionScript3.0游戏实例制作
寻宝小矿工游戏;小鱼快跑游戏;拆方层游戏;Flappy Bird游戏;2048游戏;网络坦克大战游戏
第一章 Flash游戏基础知识
主要介绍常见的Flash游戏类型、Flash网页游戏、手机游戏的发展现状 、Flash游戏制作的一般流程
第二章 ActionScript2.0基础知识
主要介绍ActionScript2.0编程基础知识,包括动作面板的基础操作、ActionScript2.0编程语言基础、事件和事件处理的使用、常用内置类的使用
第三章 开发益智类游戏
主要介绍益智类游戏的开发,通过“甜品师学习之旅”游戏的制作掌握益智类游戏开发的方法、步骤。本章涉及的知识点有startDrag()与stopDrag()的使用、getProperty()与setProperty()的使用、_droptarget属性值的使用等知识。通过本游戏的制作,学会拖动对象、获取与设置对象属性值的方法、_droptarget属性值的使用技巧,掌握游戏中影片剪辑元件、按钮元件的制作技巧、学会游戏计分的方法,能够制作出类似的游戏。
第四章 开发动作类游戏
主要介绍动作类游戏的开发,通过“小鸟出窝”游戏的制作掌握益智类游戏开发的方法、步骤。本章涉及的新知识点有setInterval()方法的使用、随机数的获取、鼠标跟随的实现等知识。通过本游戏的制作,应该学会使用setInterval()方法设置时间间隔、使用Math.random()方法获取随机数值、使用startDrag()方法实现鼠标跟随,掌握游戏中小鸟元件的制作方法,学会游戏中计分的方法,掌握&小鸟出窝&游戏的制作技巧。
第五章 ActionScript3.0游戏基础
本章主要介绍ActionScript3.0开发游戏的基础知识,包括包、类、对象、函数、事件侦听机制等概念,键盘、鼠标事件的使用,使用Event.ENTER_FRAME事件和Timer类在游戏中触发连续动作,FlashDevelop的配置与使用,以及AS3.0游戏的一般框架。
第六章 建立游戏框架
本章主要在游戏框架的基础上实现&寻宝小矿工&游戏,通过游戏的制作,掌握游戏框架的概念,学会使用游戏框架开发游戏。本章涉及的新知识点有数组的使用、声音的使用等。通过本游戏的制作,应掌握使用AS3.0制作游戏的一般架构,学会使用函数,掌握游戏中宝箱排列、宝石匹配的方法,掌握计分、计时、关卡的设定技巧。
第七章 碰撞检测的实现
本章主要介绍游戏中碰撞检测的实现,通过“小鱼快跑”游戏的制作,深入体会函数的作用、随机数值的获取、碰撞效果的实现,掌握游戏中产生鱼、鱼移动的方法,掌握计分、计时、关卡的设定技巧。
第八章 游戏引擎的使用
本章主要介绍游戏引擎的概念及作用,并且通过对“方块头大冒险”游戏介绍了Tweening引擎和Box2D引擎的使用方法。通过本游戏的制作,应该掌握如何使用第三方的ActionScript游戏引擎,掌握游戏架构设计、主函数中处理函数的设定与调用、多关卡切换处理方法等技巧
第九章 开发Android平台游戏
本章主要介绍如何使用Flash开发Android平台游戏,通过“flappybird游戏”的开发,要掌握移动平台游戏开发的一些基本知识,掌握简单的游戏场景处理方式,掌握使用Vector模型处理对象,并巩固游戏设计的基本流程等技巧。
第十章 开发
iOS平台游戏
本章主要介绍如何使用Flash开发
iOS平台游戏,通过“2048游戏”的开发,掌握iOS平台下开发的基本知识,掌握移动设备中触控事件的处理方式,掌握使用数学模型的方法实现游戏的处理,并巩固游戏设计的基本流程等技巧。
第十一章 开发网页游戏
本章主要介绍如何使用Flash开发网页游戏,通过“网络坦克大战游戏”的开发,掌握网页游戏的基本知识,掌握Flash网络通信开发的基本结构,掌握网络游戏服务器端和客户端开发的基本方法,最终实现网页客户端与服务器进行即时通信和交互的任务。

我要回帖

更多关于 flappy bird毕业设计 的文章

 

随机推荐