int dy = p.y() - _gravity.y(); int dx = p.x() - _gravity.x(); qint64 key = (dist << 32) + (dy << 16) + dx;
时间: 2024-05-17 19:14:29 浏览: 107
这几行代码是计算每个扩展(_expns)的排序关键字,以便对它们进行排序。其中,dy 和 dx分别表示扩展相对重心的 y 坐标和 x 坐标的偏移量,dist 是扩展和重心之间的曼哈顿距离(ManhattanLength),计算曼哈顿距离的函数在这段代码中没有给出。最后,将这三个值组合成一个qint64类型的排序关键字key,其中dist占据高32位,dy占据中间16位,dx占据低16位。
相关问题
编译器:C++ (g++) Particle类型用于表示处于三维空间中的质点,其包括如下成员:① 三个浮点数成员x、y和z表示质点在三维空间中的坐标;② 浮点数成员mass表示质点的质量;③ 接受空间坐标和质量参数的构造函数;④ 自定义operator-()操作符函数用于计算两个质点间的万有引力,即表达式p1 – p2调用执行p1的operator-()操作符函数,计算质点p1和p2间的万有引力。 万有引用公式F = GMm/r²中,万有引力常数G = 6.67×10-11N·m²/kg²。 请依据上述描述,设计Particle类,使得下述代码能正常执行。 注意:天文数字都很大,建议浮点数全部采用long double类型。 裁判测试程序样例: #include <iostream> #include <cmath> using namespace std; //在此处定义Particle类及其重载operator+()操作符函数 int main() { long double x, y, z, mass; cin >> x >> y >> z >> mass; Particle p1(x,y,z,mass); cin >> x >> y >> z >> mass; const Particle p2(x,y,z,mass); long double force = p1 - p2; printf("Gravity between two objects = %.1Lf N",force); return 0; } 输入样例: 0 0 0 5.965e15 0 0 38400000 7.342e14 输出样例: Gravity between two objects = 198101.7 N 说明:输入输出中的所有数据均为标准单位,坐标为米,质量为kg。 请注意:函数题只需要提交相关代码片段,不要提交完整程序。
代码如下:
```c++
#include <iostream>
#include <cmath>
using namespace std;
class Particle{
private:
long double x, y, z, mass;
public:
Particle(long double x=0, long double y=0, long double z=0, long double mass=0){
this->x = x;
this->y = y;
this->z = z;
this->mass = mass;
}
long double operator-(const Particle& p2){
const long double G = 6.67e-11;
long double dx = x - p2.x;
long double dy = y - p2.y;
long double dz = z - p2.z;
long double r = sqrt(dx*dx + dy*dy + dz*dz);
return G * mass * p2.mass / (r * r);
}
};
int main(){
long double x, y, z, mass;
cin >> x >> y >> z >> mass;
Particle p1(x,y,z,mass);
cin >> x >> y >> z >> mass;
const Particle p2(x,y,z,mass);
long double force = p1 - p2;
printf("Gravity between two objects = %.1Lf N",force);
return 0;
}
```
swift语言实战晋级-第9章 游戏实战-跑酷熊猫-3
在跑酷熊猫游戏中,我们已经实现了熊猫在一条无限循环的道路上奔跑,并且可以通过左右滑动来避开障碍物。现在我们要添加更多的游戏元素,使游戏更加有趣。
## 1. 道路随机生成
我们要让游戏中的道路不再是一条固定的直线,而是随机生成的。我们可以通过几个步骤来实现这个功能:
### 1.1 创建地图
我们先创建一个地图类,用来表示游戏中的道路。地图由多个段组成,每个段包含一个随机生成的道路和一些障碍物。
```swift
class Map {
var segments = [Segment]()
init() {
generateSegments()
}
func generateSegments() {
// 生成一些段,每个段包含一个随机生成的道路和一些障碍物
}
}
```
### 1.2 随机生成道路
我们可以定义一个 `Road` 结构体,表示一段道路。道路由多个点组成,每个点包含一个 x 坐标和一个 y 坐标。
```swift
struct Road {
var points = [CGPoint]()
}
```
在 `Map` 类中,我们可以实现一个方法来随机生成一段道路。我们可以先生成一些控制点,然后通过这些控制点计算出道路上的点。
```swift
func generateRoad() -> Road {
let startX = CGFloat.random(in: -100...100)
let startY = CGFloat.random(in: -100...100)
let endX = CGFloat.random(in: -100...100)
let endY = CGFloat.random(in: -100...100)
let controlX1 = CGFloat.random(in: -100...100)
let controlY1 = CGFloat.random(in: -100...100)
let controlX2 = CGFloat.random(in: -100...100)
let controlY2 = CGFloat.random(in: -100...100)
let tValues = stride(from: 0, through: 1, by: 0.01)
let points = tValues.map { t -> CGPoint in
let x = pow(1-t, 3) * startX + 3 * pow(1-t, 2) * t * controlX1 + 3 * (1-t) * pow(t, 2) * controlX2 + pow(t, 3) * endX
let y = pow(1-t, 3) * startY + 3 * pow(1-t, 2) * t * controlY1 + 3 * (1-t) * pow(t, 2) * controlY2 + pow(t, 3) * endY
return CGPoint(x: x, y: y)
}
return Road(points: points)
}
```
这个方法会生成一个随机的起点和终点,以及两个控制点。然后使用贝塞尔曲线计算出道路上的点,并返回一个 `Road` 结构体。
### 1.3 随机生成障碍物
在每个段中,我们还需要随机生成一些障碍物。我们可以定义一个 `Obstacle` 结构体,表示一个障碍物。障碍物由多个点组成,每个点包含一个 x 坐标和一个 y 坐标。
```swift
struct Obstacle {
var points = [CGPoint]()
}
```
在 `Map` 类中,我们可以实现一个方法来随机生成一些障碍物。我们可以先生成一些控制点,然后通过这些控制点计算出障碍物上的点。
```swift
func generateObstacle() -> Obstacle {
let startX = CGFloat.random(in: -50...50)
let startY = CGFloat.random(in: -50...50)
let endX = CGFloat.random(in: -50...50)
let endY = CGFloat.random(in: -50...50)
let controlX1 = CGFloat.random(in: -50...50)
let controlY1 = CGFloat.random(in: -50...50)
let controlX2 = CGFloat.random(in: -50...50)
let controlY2 = CGFloat.random(in: -50...50)
let tValues = stride(from: 0, through: 1, by: 0.01)
let points = tValues.map { t -> CGPoint in
let x = pow(1-t, 3) * startX + 3 * pow(1-t, 2) * t * controlX1 + 3 * (1-t) * pow(t, 2) * controlX2 + pow(t, 3) * endX
let y = pow(1-t, 3) * startY + 3 * pow(1-t, 2) * t * controlY1 + 3 * (1-t) * pow(t, 2) * controlY2 + pow(t, 3) * endY
return CGPoint(x: x, y: y)
}
return Obstacle(points: points)
}
```
这个方法会生成一个随机的起点和终点,以及两个控制点。然后使用贝塞尔曲线计算出障碍物上的点,并返回一个 `Obstacle` 结构体。
### 1.4 生成多个段
有了上面两个方法,我们就可以在 `Map` 类中实现一个方法来生成多个段了。每个段包含一个随机生成的道路和一些障碍物。我们可以随机生成一些段,然后将这些段添加到 `segments` 数组中。
```swift
func generateSegments() {
segments.removeAll()
var lastEnd = CGPoint.zero
for _ in 0..<10 {
let road = generateRoad()
let obstacleCount = Int.random(in: 1...3)
var obstacles = [Obstacle]()
for _ in 0..<obstacleCount {
obstacles.append(generateObstacle())
}
let segment = Segment(road: road, obstacles: obstacles, start: lastEnd)
segments.append(segment)
lastEnd = road.points.last!
}
}
```
这个方法会生成 10 个随机的段,并将它们添加到 `segments` 数组中。每个段的起点都和上一个段的终点相连,形成一条无限循环的道路。
### 1.5 显示地图
现在我们已经生成了一个随机的地图,接下来要将它显示在游戏中。我们可以在 `GameScene` 类中添加一个 `map` 属性,并在 `didMove(to:)` 方法中创建这个地图。
```swift
class GameScene: SKScene {
var panda: Panda!
var map: Map!
override func didMove(to view: SKView) {
panda = Panda()
addChild(panda)
map = Map()
for segment in map.segments {
let roadNode = SKShapeNode(splinePoints: segment.road.points, count: segment.road.points.count)
roadNode.strokeColor = .white
roadNode.lineWidth = 3
addChild(roadNode)
for obstacle in segment.obstacles {
let obstacleNode = SKShapeNode(splinePoints: obstacle.points, count: obstacle.points.count)
obstacleNode.strokeColor = .red
obstacleNode.lineWidth = 3
addChild(obstacleNode)
}
}
}
}
```
在 `didMove(to:)` 方法中,我们先创建一个熊猫节点,并将它添加到场景中。然后创建一个地图对象,遍历地图中的每个段,创建一个道路节点和一些障碍物节点,并将它们添加到场景中。
现在运行游戏,就会看到一条随机生成的道路和一些随机生成的障碍物了!
## 2. 碰撞检测
我们已经随机生成了一些障碍物,现在要实现碰撞检测,当熊猫碰到障碍物时,游戏就结束。
### 2.1 添加物理引擎
要进行碰撞检测,我们需要使用 SpriteKit 中的物理引擎。在 `GameScene` 类中,我们可以添加一个物理世界,并将熊猫和障碍物添加到这个世界中。
```swift
class GameScene: SKScene {
var panda: Panda!
var map: Map!
var world: SKPhysicsWorld!
override func didMove(to view: SKView) {
panda = Panda()
addChild(panda)
map = Map()
for segment in map.segments {
let roadNode = SKShapeNode(splinePoints: segment.road.points, count: segment.road.points.count)
roadNode.strokeColor = .white
roadNode.lineWidth = 3
addChild(roadNode)
for obstacle in segment.obstacles {
let obstacleNode = SKShapeNode(splinePoints: obstacle.points, count: obstacle.points.count)
obstacleNode.strokeColor = .red
obstacleNode.lineWidth = 3
addChild(obstacleNode)
let physicsBody = SKPhysicsBody(polygonFrom: obstacle.points)
physicsBody.categoryBitMask = 1
physicsBody.contactTestBitMask = 2
obstacleNode.physicsBody = physicsBody
}
}
physicsWorld.gravity = CGVector(dx: 0, dy: -9.8)
physicsWorld.contactDelegate = self
world = physicsWorld
}
}
```
在 `didMove(to:)` 方法中,我们先创建一个熊猫节点,并将它添加到场景中。然后创建一个地图对象,遍历地图中的每个障碍物,创建一个障碍物节点,并将它添加到场景中。同时为障碍物添加一个物理体,并设置它的分类掩码和接触测试掩码。最后设置物理世界的重力和接触代理。
### 2.2 检测碰撞
在 `GameScene` 类中,我们还需要实现 `SKPhysicsContactDelegate` 协议中的 `didBegin(_:)` 方法,检测熊猫和障碍物之间的碰撞。
```swift
class GameScene: SKScene, SKPhysicsContactDelegate {
// ...
func didBegin(_ contact: SKPhysicsContact) {
if contact.bodyA.node == panda || contact.bodyB.node == panda {
gameOver()
}
}
func gameOver() {
print("Game Over")
// 处理游戏结束
}
}
```
在 `didBegin(_:)` 方法中,我们检查熊猫和障碍物是否发生了碰撞,如果发生了碰撞,就调用 `gameOver()` 方法,处理游戏结束的逻辑。
### 2.3 开启碰撞检测
最后,我们还需要在 `Panda` 类中开启碰撞检测。
```swift
class Panda: SKSpriteNode {
init() {
// ...
let physicsBody = SKPhysicsBody(texture: texture!, size: size)
physicsBody.categoryBitMask = 2
physicsBody.contactTestBitMask = 1
physicsBody.collisionBitMask = 0
physicsBody.affectedByGravity = true
physicsBody.allowsRotation = false
physicsBody.velocity.dy = 200
physicsBody.angularVelocity = 0
physicsBody.linearDamping = 0
physicsBody.angularDamping = 0
physicsBody.restitution = 0
physicsBody.friction = 0
physicsBody.mass = 1
self.physicsBody = physicsBody
}
}
```
在 `Panda` 类的初始化方法中,我们创建一个物理体,并设置它的分类掩码、接触测试掩码、碰撞掩码、重力、旋转等属性。最后将物理体添加到熊猫节点上。
现在运行游戏,当熊猫碰到障碍物时,游戏就会结束了!
## 3. 总结
在本章中,我们学习了如何让游戏中的道路随机生成,并实现了碰撞检测的功能。下一章中,我们将继续完善游戏,添加更多的功能和效果。
阅读全文