问题描述
//The following game has been designed as an educational resource
//for Key Stage 1 and 2 children. Children are the future of
//civil engineering,and to inspire them to get involved in the
//industry is important for innovation. However,today the
//national curriculum is very structured,and many children
//can find themselves falling behind even at the age of 7 or 8.
//It is essential that children can be supported with material
//they find difficult,and given the resources to learn in a
//fun and engaging manner.
//One of the topics that many children struggle to grasp is
//fractions. It is necessary to prevent young children feeling
//like stem subjects are too difficult for them,so that they
//have the opportunity and confidence to explore science and
//engineering subjects as they move into secondary education and
//careers.
//This game intends to set a precedent for teaching complex
//subjects to children in a simple,but fun and interactive
//manner. It will show them that fractions can be fun,and that
//they are capable,building confidence once they return to
//the classroom.
//The game will work by challenging the user to split a group
//of balls into three buckets depending on the fraction
//displayed on the bucket.
int number_of_balls;
float bucket_1,bucket_2,bucket_3;
int bucket_1_correct,bucket_2_correct,bucket_3_correct;
PVector basket_position,basket_dimensions;
Ball[] array_of_balls;
int linethickness;
//Random generator to give number of balls,ensuring that
//they can be divided into the number of buckets available.
void setup()
{
size(500,500);
linethickness = 4;
number_of_balls = int(random(1,11))*6;
println(number_of_balls);
bucket_1 = 1/6;
bucket_2 = 1/2;
bucket_3 = 1/3;
//Working out the correct answers
bucket_1_correct = number_of_balls*bucket_1;
bucket_2_correct = number_of_balls*bucket_2;
bucket_3_correct = number_of_balls*bucket_3;
println (bucket_1,bucket_3);
println (bucket_1_correct,bucket_3_correct);
//Creating the basket
basket_position = new PVector(width/4,height/8);
basket_dimensions = new PVector(width/2,height/4);
//Creating the balls & placing inside basket
array_of_balls = new Ball[number_of_balls];
for (int index=0; index<number_of_balls; index++)
{
array_of_balls[index] = new Ball();
}
}
//Drawing the balls and basket outline
void draw()
{
background (125,95,225);
for (int index=0; index<number_of_balls; index++)
{
array_of_balls[index].Draw();
}
noFill();
stroke(180,0);
strokeWeight(linethickness);
rect(basket_position.x,basket_position.y,basket_dimensions.x,basket_dimensions.y);
}
void mouseDragged()
{
if ((mouseX >= (ball_position.x - radius)) && (mouseX <= (ball_position.x + radius)) && (mouseY >= (ball_position.y - radius)) && (mouseY <= (ball_position.y + radius)))
{
ball_position = new PVector (mouseX,mouseY);
}
}
//Ball_class
int radius;
Ball()
{
radius = 10;
ball_position = new PVector (random(basket_position.x + radius + linethickness,basket_position.x + basket_dimensions.x - radius - linethickness),random(basket_position.y + radius + linethickness,basket_position.y + basket_dimensions.y - radius - linethickness));
colour = color(random(255),random(255),random(255));
}
void Draw()
{
nostroke();
fill(colour);
ellipse(ball_position.x,ball_position.y,radius*2,radius*2);
}
}
在此先感谢您的帮助!我正在使用 Processing 2.2.1,我知道它已经过时了,所以很难找到帮助。
我有一段代码创建了许多球,我希望能够将它们“拖放”到屏幕上的不同位置,作为教育游戏的一部分。我试过玩弄 mousepressed()
和 mouseDragged()
但还没有运气。任何建议将不胜感激!
解决方法
我对您使用的语言有些困惑。 Processing 是 Java 的包装器,而不是 JavaScript。 Processing.js 升级到 1.6.6 版本,然后被 p5.js 接替。我假设您使用的是 p5.js。
我不知道这是否是 p5.js 中的新事物,但为了简单但不是非常用户友好的点击和拖动功能,我喜欢使用内置变量 mouseIsPressed
。
如果椭圆坐标存储在向量数组中,您可能会执行以下操作:
let balls = [];
let radius = 10;
function setup() {
createCanvas(400,400);
for (let i = 0; i < 10; i++) {
balls.push(createVector(random(width),random(height)));
}
}
function draw() {
background(220);
for (let i = 0; i < balls.length && mouseIsPressed; i++) {
if (dist(mouseX,mouseY,balls[i].x,balls[i].y) < radius) {
balls[i] = createVector(mouseX,mouseY);
i = balls.length;
}
}
for (let i = 0; i < balls.length; i++) {
ellipse(balls[i].x,balls[i].y,2 * radius,2 * radius
);
}
}
这是我能想到的最快的方法,但还有更好的方法(至少,在 p5.js 中有)。您可以创建一个 Ball
类,其中包含 x、y 和半径的数字,以及一个表示是否被拖动的布尔值。在该类中,您可以创建一个方法 mouseOn()
来检测光标是否在半径内(如果不是圆形,您可以使用两个半径:sq((this.x - mouseX)/r1) + sq((this.y - mouseY)/r2) < 1
)。
当按下鼠标时,您可以循环遍历球数组中的所有球,并使用 mouseOn()
测试每个球,并将它们的拖动布尔值设置为 true。释放鼠标后,您可以将所有拖动布尔值设置为 false。这是当前版本的 p5.js 中的样子:
function mousePressed() {
for (let i = 0; i < balls.length; i++) {
balls[i].drag = balls[i].mouseOn();
if (balls[i].drag) {
i = balls.length;
}
}
}
function mouseReleased() {
for (let i = 0; i < balls.length; i++) {
balls[i].drag = false;
}
}
我希望这会有所帮助。
,有很多方法可以解决这个问题,但我建议的一种方法是做这样的事情:
// "Ellipse" object
function Ellipse (x,y,width,height) {
// Each Ellipse object has their own x,height,and "selected" values
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.selected = false;
// You can call the draw function whenever you want something done with the object
this.draw = function() {
// Draw ellipse
ellipse(this.x,this.y,this.width,this.height);
// Check if mouse is touching the ellipse using math
// https://www.desmos.com/calculator/7a9u1bpfvt
var xDistance = this.x - mouseX;
var yDistance = this.y - mouseY;
// Ellipse formula: (x^2)/a + (y^2)/b = r^2
// Assuming r = 1 and y = 0:
// 0 + (x^2)/a = 1 Substitute values
// ((width / 2)^2)/a = 1 x = width / 2 when y = 0
// a = (width / 2)^2 Move numbers around
// a = (width^2) / 4 Evaluate
var a = Math.pow(this.width,2) / 4;
// Assuming r = 1 and x = 0:
// 0 + (y^2)/b = 1 Substitute values
// ((height / 2)^2)/b = 1 y = height / 2 when x = 0
// b = (height / 2)^2 Move numbers around
// b = (height^2) / 4 Evaluate
var b = Math.pow(this.height,2) / 4;
// x^2
var x2 = Math.pow(xDistance,2);
// y^2
var y2 = Math.pow(yDistance,2);
// Check if coordinate is inside ellipse and mouse is pressed
if(x2 / a + y2 / b < 1 && mouseIsPressed) {
this.selected = true;
}
// If mouse is released,deselect the ellipse
if(!mouseIsPressed) {
this.selected = false;
}
// If selected,then move the ellipse
if(this.selected) {
// Moves ellipse with mouse
this.x += mouseX - pmouseX;
this.y += mouseY - pmouseY;
}
};
}
// New Ellipse object
var test = new Ellipse(100,100,90,60);
draw = function() {
background(255);
// Do everything associated with that object
test.draw();
};
数学有点奇怪,我可能没有使用正确版本的 Processing,但希望你发现这至少有点帮助 :)
,您的代码现在的方式在当前版本的 Processing 中也不起作用,但这是一个非常快速的修复。我将向您展示解决该问题的方法,希望它可以在早期版本中使用。
这里是我认为问题所在:当您使用 mouseDragged()
时,您尝试更改 ball_position
,但您没有指定哪个球的位置。这是一种解决方案,更改 mouseDragged()
块和 Ball
类:
void mouseDragged() {
for (int i = 0; i < array_of_balls.length; i++) {
if ((mouseX > (array_of_balls[i].ball_position.x - array_of_balls[i].radius)) &&
(mouseX < (array_of_balls[i].ball_position.x + array_of_balls[i].radius)) &&
(mouseY > (array_of_balls[i].ball_position.y - array_of_balls[i].radius)) &&
(mouseY < (array_of_balls[i].ball_position.y + array_of_balls[i].radius))
) {
array_of_balls[i].ball_position = new PVector (mouseX,mouseY);
i = array_of_balls.length;
}
}
}
//Ball_class
class Ball {
int radius;
PVector ball_position;
color colour;
Ball() {
radius = 10;
ball_position = new PVector (random(basket_position.x + radius + linethickness,basket_position.x + basket_dimensions.x - radius - linethickness),random(basket_position.y + radius + linethickness,basket_position.y + basket_dimensions.y - radius - linethickness));
colour = color(random(255),random(255),random(255));
}
void Draw() {
noStroke();
fill(colour);
ellipse(ball_position.x,ball_position.y,radius*2,radius*2);
}
}
附言由于您使用的是基于 Java 的语言,因此您可能应该遵守该语言的一些细节:
- Java 中的数据类型非常严格。避免将任何可能是浮点数的变量分配给声明为 int 的变量。例如,在您的
setup()
块中,您说bucket_1_correct = number_of_balls*bucket_1;
。这似乎不是问题,因为number_of_balls*bucket_1
始终是整数。但是由于计算机在保存bucket_1 = 1/6
时会四舍五入,因此将其乘以 6 不一定会给出整数。在这种情况下,您可以只使用round()
:bucket_1_correct = round(number_of_balls*bucket_1);
- 关于数据类型,您应该始终使用其数据类型声明变量。我有点难以判断,但在我看来,您从未在
ball_position
类中声明colour
或Ball
,并且您从未使用典型的 {{ 1}}。不过,这可能是复制/粘贴错误。