cocos2d-x3.0和物理引擎来制作一个Breakout游戏1

2024-01-19 16:40

本文主要是介绍cocos2d-x3.0和物理引擎来制作一个Breakout游戏1,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


说明:这个两篇的小系列基本上是基于COCOS2D-X自身携带的DEMO中示例的简单延伸,此中我们主要了解在3.0版本中对于物理引擎的进一步的简单包装而已。

原文URL:http://www.cocos2d-x.org/docs/tutorial/framework/native/how-to-create-a-simple-breakout-game-with-box2d-and-cocos2dx-tutorial/part1/zh


前言

image

在这个教程中,我们将一步一步创建一个简单的breakout游戏,完成碰撞检测,篮球反弹物理效果,通过touch拖动paddle(就是上图的白色矩形),以及胜利/失败的场景。

如果你还不了解cocos2d-x和其封装的物理引擎,你可能先要读一读《如何用cocos2d-x3.0制作一款简单的游戏》以及《在cocos2d-x3.0里面如何使用物理引擎:弹球》这些教程。

好了,是时候制作breakout了!

一个永远反弹的球

首先创建一个空项目。

接下来,在HelloWorldScene.h中添加以下成员变量:

Sprite* ball;Sprite* paddle;Sprite* edgeSp;PhysicsWorld* m_world;void setPhyWorld(PhysicsWorld* world){ m_world = world; };

然后,在init方法中加入下列代码:

auto visibleSize = Director::getInstance()->getVisibleSize();auto origin = Director::getInstance()->getVisibleOrigin();edgeSp = Sprite::create();auto boundBody = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);boundBody->getShape(0)->setRestitution(1.0f);boundBody->getShape(0)->setFriction(0.0f);boundBody->getShape(0)->setDensity(1.0f);edgeSp->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));edgeSp->setPhysicsBody(boundBody);this->addChild(edgeSp);edgeSp->setTag(0);

好,这个代码和我们上一个教程中,为整个屏幕创建一个盒子边界差不多。然后,这一次,我们把重力设置为0,因为,在我们的breakout游戏中,我们并不需要重力!

让我们往场景里面添加一个精灵并为其创建body。紧接着上面的代码,加入下面的代码片段:

ball = Sprite::create("Ball.png", Rect(0, 0, 52, 52));ball->setPosition(100, 100);auto ballBody = PhysicsBody::createCircle(ball->getContentSize().width / 2.);ballBody->getShape(0)->setRestitution(1.0f);ballBody->getShape(0)->setFriction(0.0f);ballBody->getShape(0)->setDensity(1.0f);ballBody->setGravityEnable(false);Vect force = Vect(1000000.0f, 1000000.0f);ballBody->applyImpulse(force);ball->setPhysicsBody(ballBody);ball->setTag(1);this->addChild(ball);

注意,我们设置这些参数有一点点不一样了:我们把回复力(restitution)设置为1.0,这意味着,我们的球在碰撞的时候,将会是完全弹性碰撞。

注意,我们也把球的摩擦力设置为0.这样可以防止球在碰撞的时候,由于摩擦损失能量,导致来回碰撞的过程中会有一点点偏差。

Vect force = Vect(1000000.0f, 1000000.0f);ballBody->applyImpulse(force);

这里往球上面施加了一个冲力(impulse),这样可以让它初始化的时候朝一个特定的方向运动。

好了,让我们试一下吧。编译并运行工程,你将会看到一个球无限地在屏幕里面来回弹!----很酷吧!

image

增加 Paddle

如果没有一个paddle的话,那么就不可能称其为一个breakout游戏。

在init方法中构建paddle body:

paddle = Sprite::create("Paddle.png");auto paddleBody = PhysicsBody::createBox(paddle->getContentSize(), PHYSICSBODY_MATERIAL_DEFAULT);paddleBody->getShape(0)->setRestitution(1.0f);paddleBody->getShape(0)->setFriction(0.0f);paddleBody->getShape(0)->setDensity(10.0f);paddleBody->setGravityEnable(false);paddleBody->setDynamic(false);paddle->setPosition(visibleSize.width / 2, 50);paddle->setPhysicsBody(paddleBody);ball->setTag(2);this->addChild(paddle);

如果你编译并运行的话,你将会看到屏幕中间有一个paddle,而且球碰到它将会反弹。

image

移动Paddle

移动paddle需要touch事件,所以先在onEnter方法中允许touch和监听碰撞事件(后面会用到):

void HelloWorld::onEnter()
{
   Layer::onEnter();

auto listener = EventListenerTouchOneByOne::create();listener->setSwallowTouches(true);listener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);auto contactListener = EventListenerPhysicsContact::create();contactListener->onContactBegin = CC_CALLBACK_2(HelloWorld::onContactBegin, this);auto dispatcher = Director::getInstance()->getEventDispatcher();dispatcher->addEventListenerWithSceneGraphPriority(listener, this);dispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);

}

现在,让我们实现touch方法!首先是onTouchMoved:

void HelloWorld::onTouchMoved(Touch* touch, Event* event){Point touchLocation = this->convertToWorldSpace(this->convertTouchToNodeSpace(touch));paddle->setPositionX(touchLocation.x);}

限制Paddle的移动

只需要改变paddle的X值就限制了paddle的移动

paddle->setPositionX(touchLocation.x);

编译并运行,你只能沿关x轴方向移动paddle,这正是我们想要的,不是吧?

image

给我源代码!

  这里是本教程的完整源代码

  这里是本教程的完整源代码。这只是一部分,第二部分的教程会包含一个完整的breakout的源码。

接下来呢?

  目前为止,我们已经有一个篮球在屏幕四周来回反弹了,同时还有一个paddle可以用鼠标来控制其移动。在下个教程中,我们将创建一些方块,当 球碰到它们的时候,方块就会消失。当然,还有游戏胜利和失败的逻辑!)。这只是一部分,第二部分的教程会包含一个完整的breakout的源码。

接下来呢?

目前为止,我们已经有一个篮球在屏幕四周来回反弹了,同时还有一个paddle可以用鼠标来控制其移动。在下个教程中,我们将创建一些方块,当球碰到它们的时候,方块就会消失。当然,还有游戏胜利和失败的逻辑!


这篇关于cocos2d-x3.0和物理引擎来制作一个Breakout游戏1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/623034

相关文章

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

MySQL 存储引擎 MyISAM详解(最新推荐)

《MySQL存储引擎MyISAM详解(最新推荐)》使用MyISAM存储引擎的表占用空间很小,但是由于使用表级锁定,所以限制了读/写操作的性能,通常用于中小型的Web应用和数据仓库配置中的只读或主要... 目录mysql 5.5 之前默认的存储引擎️‍一、MyISAM 存储引擎的特性️‍二、MyISAM 的主

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

MySQL常见的存储引擎和区别说明

《MySQL常见的存储引擎和区别说明》MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY、Archive、CSV和Blackhole,每种引擎有其特点和适用场景,选择存储引擎时需根... 目录mysql常见的存储引擎和区别说明1. InnoDB2. MyISAM3. MEMORY4. A

MySQL InnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据

《MySQLInnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据》mysql的ibdata文件被误删、被恶意修改,没有从库和备份数据的情况下的数据恢复,不能保证数据库所有表数据... 参考:mysql Innodb表空间卸载、迁移、装载的使用方法注意!此方法只适用于innodb_fi