如何使用cocos2d-x3.0和物理引擎来制作一个Breakout游戏:第一部分

2024-01-19 16:40

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

前言

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游戏:第一部分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MyBatis ParameterHandler的具体使用

《MyBatisParameterHandler的具体使用》本文主要介绍了MyBatisParameterHandler的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、概述二、源码1 关键属性2.setParameters3.TypeHandler1.TypeHa

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完