|
3D-программирование Вопросы, касающиеся программирования 3D мира |
02.03.2012, 21:58
|
#1
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Упорядоченное исчезновение объектов
У меня проблема: мне нужно, чтобы при выстреле в блок он изчезал, я создал тип, и всё как бы работает, но если я сделаю выстрел в один из блоков, то ещё уничтожить можно будет только блоки с порядковым номером меньше первого исчезнувшего, т.е. у меня 8 блоков:01234567, если я стреляю в 4, он исчезает и ещё можно уничтожить 012 и 3, а 567 - нельзя...Как этого избежать?
Вот код:
Graphics3D 640,480,16,1
SetBuffer BackBuffer()
pl_j = 0
fall=1
gravity# = 0.09
yspeed#=0
jspeed = 1.40
health=100
Global Tplayer = 1, Tblock = 2, TYPE_BULLET = 3
Global cam
Type Bullet
Field rot#,sprite,time_out
End Type
Type blocks
Field ent
End Type
;----------TEXTURES----------;
pln=CreatePlane()
PositionEntity pln,0,-10,0
EntityType pln,Tblock
EntityColor pln,50,100,150
block=CreateCube()
PositionEntity block,0,1000,0
EntityType block,Tblock
EntityColor block,255,0,0
ScaleEntity block,5,4,5
HideEntity block
Global bull_sprite=LoadSprite("bluspark.bmp")
ScaleSprite bull_sprite,3,3
EntityRadius bull_sprite,1.5
EntityType bull_sprite,TYPE_BULLET
HideEntity bull_sprite
laser=LoadSound("laser.ogg")
;map=LoadMesh("levels\level1\level.b3d")
;lightmap=LoadTexture("levels\level1\lightmap.tga")
;TextureCoords lightmap,1
;TextureBlend(lightmap,5)
;EntityTexture map,lightmap,0,1
;FreeTexture lightmap
;PositionEntity map,0,-100,0
;ScaleEntity map,0.3,0.3,0.3
;EntityType map, Tblock
;----------END TEXTURES----------;
;----------MAIN----------;
Global player=CreateSphere()
EntityColor player,255,0,0
PositionEntity player,0,0,0
EntityRadius player,5
EntityRadius player,4
EntityType player, Tplayer
EntityAlpha player,0
cam=CreateCamera(player)
PositionEntity cam,0,3,-2
EntityType cam, Tplayer
gun=LoadMesh("models\level1\gun.3ds")
ScaleEntity gun,0.03,0.03,0.03
EntityParent gun,cam
PositionEntity gun,-1,-4,0
RotateEntity gun,0,-90,0
pivo=CreateSphere()
PositionEntity pivo,-1,1.5,3
EntityParent pivo,gun
EntityAlpha pivo,0
;----------END MAIN----------;
Collisions Tplayer, Tblock, 2, 3
Collisions TYPE_BULLET, Tblock, 2, 2
Dim AllBlocks.blocks(8)
For i=0 To 7
AllBlocks(i) = New blocks
AllBlocks(i)\ent = CopyEntity(block)
Next
PositionEntity AllBlocks(0)\ent,0,-6,5
PositionEntity AllBlocks(1)\ent,0,-2,-15
PositionEntity AllBlocks(2)\ent,0,2,-35
PositionEntity AllBlocks(3)\ent,0,6,-55
PositionEntity AllBlocks(4)\ent,20,10,-55
PositionEntity AllBlocks(5)\ent,40,14,-55
PositionEntity AllBlocks(6)\ent,60,18,-55
PositionEntity AllBlocks(7)\ent,60,22,-35
While Not KeyHit(1)
For i=0 To 7
Local hide% = EntityCollided(AllBlocks(i)\ent, TYPE_BULLET)
If hide<>0
HideEntity AllBlocks(i)\ent
Exit
EndIf
Next
TurnEntity player, 0, 0 -MouseXSpeed()*0.1, 0
TurnEntity cam, MouseYSpeed()*0.1, 0, 0
MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
RotateEntity cam, EntityPitch#(cam), 0, 0
x#=EntityX(player)
y#=EntityY(player)
z#=EntityZ(player)
pitch#=EntityPitch(cam)
yaw#=EntityYaw(player)
roll#=EntityRoll(player)
If MouseHit(1)
CreateBullet(pivo)
PlaySound laser
EndIf
If KeyDown(17) MoveEntity player,0,0,0.5
If KeyDown(31) MoveEntity player,0,0,-0.5
If KeyDown(30) MoveEntity player,-0.5,0,0
If KeyDown(32) MoveEntity player,0.5,0,0
For b.Bullet=Each Bullet
UpdateBullet( b )
Next
HidePointer
UpdateWorld
RenderWorld
;----------GRAVITY----------;
yspeed=yspeed-gravity
TranslateEntity player,0,yspeed,0
;-----END-----;
coll = EntityCollided(player,Tblock)
If coll
collide_y = CollisionNY(player,CountCollisions(player) )
If 0<collide_y
If yspeed<-3
health=health+yspeed*3
EndIf
yspeed=0
jump=1
Else
jump=0
EndIf
Else
jump=0
EndIf
;-----JUMP-----;
If jump=1
If KeyDown(57)
yspeed = jspeed
EndIf
EndIf
;----------END JUMP----------;
Text 40, 450,Str(health)
Text 450,450,Str(yspeed)
Text 300,300,Str(x)
Text 350,300,Str(y)
Text 400,300,Str(z)
Text 300,350,Str(pitch)
Text 350,350,Str(yaw)
Text 400,350,Str(roll)
Flip
Wend
End
;------------------------------
Function CreateBullet.Bullet(pivo)
b.Bullet=New Bullet
b\time_out=150
b\sprite=CopyEntity( bull_sprite, pivo)
pitch#=EntityPitch(pivo)
RotateEntity b\sprite,pitch,0,0
EntityParent b\sprite,0
Return b
End Function
;-----------------------------------------------------------
Function UpdateBullet( b.Bullet )
b\time_out=b\time_out-1
If (b\time_out=0) Or EntityCollided( b\sprite,Tblock )
FreeEntity b\sprite
Delete b
Return
EndIf
b\rot=b\rot+30
RotateSprite b\sprite,b\rot
MoveEntity b\sprite,0,0,5
End Function
|
(Offline)
|
|
03.03.2012, 19:16
|
#2
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Сдается мне, что скрытие объекта не прекращает проверку коллизий, попробуй вместо HideEntity AllBlocks(i)\ent удалить его, хотя бы для теста. Если начнут остальные удаляться, то косяк здесь.
Еще по коду:
jspeed = 1.40 — интовая переменная, а с дробным значением
HidePointer — вызываешь в цикле, а достаточно перед циклом 1 раз
стиль именования переменных пляшет
|
(Offline)
|
|
03.03.2012, 20:08
|
#3
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Спасибо за замечания, исправил
Delete AllBlocks(i)\ent не работает, а Delete AllBlocks(i) вообще программу выносит
|
(Offline)
|
|
04.03.2012, 00:05
|
#4
|
Знающий
Регистрация: 06.12.2010
Адрес: Луганск
Сообщений: 252
Написано 112 полезных сообщений (для 166 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Попробуй Exit убрать.
__________________
AMD Sempron(tm) 1.41Ггц, 1024МБ ОЗУ, GeForce 6200 128МБ, WinXP SP3.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
04.03.2012, 11:47
|
#5
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Спасибо большое, работает
А за что EXIT отвечает в данном случае?
|
(Offline)
|
|
04.03.2012, 16:29
|
#6
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Exit прекращает работу цикла, переводя выполнение на строку после слова Next. Не только в данном случае но и везде. Если циклы вложенные, то выйдет только из того в котором стоит Ехит.
Убрать ехит круто, но лучше этого не делать, в том смысле что та проверка на коллизию после скрытия объекта не должна работать вовсе, т.е. объект нужно исключить из проверки.
Почему бы тебе не перебирать блоки используя конструкцию for ... each как сделано для пуль? Тогда не будет вылетать после удаления и гарантированно в проверку удалённый не попадёт.
Если нужен именно массив, то можешь писать так:
For i=0 To 7
If(AllBlocks(i) <> null)
Local hide% = EntityCollided(AllBlocks(i)\ent, TYPE_BULLET)
If hide<>0
FreeEntity AllBlocks(i)\ent
Delete AllBlocks(i)
AllBlocks(i) = Null
Exit
EndIf
EndIf
Next
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
04.03.2012, 17:52
|
#7
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
for...each я пробовал и функцию отдельную делал, но я не могу понять, как в этом случае мне выделять отдельные объекты и для каждого прописывать координаты...
|
(Offline)
|
|
04.03.2012, 23:11
|
#8
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Вот ещё вопрос по коллизиям: мне, например, нужно, чтобы блоки по отдельности исчезали, не от попадания пули, а от столкновения с игроком, однако, как я не изменял код, блоки либо исчезают все вместе, либо не исчезают вообще, что делать?
|
(Offline)
|
|
05.03.2012, 03:31
|
#9
|
Разработчик
Регистрация: 06.06.2011
Адрес: Ирк. обл.
Сообщений: 541
Написано 133 полезных сообщений (для 220 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Код у тебя будет выглядеть аналогично тому, что и при попадание пуль! При поподание ты же тоже коллизию проверяешь и убираешь объект, так же и с игроком!
|
(Offline)
|
|
05.03.2012, 07:32
|
#10
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Сообщение от Devilox
for...each я пробовал и функцию отдельную делал, но я не могу понять, как в этом случае мне выделять отдельные объекты и для каждого прописывать координаты...
|
ты пули создаёшь, и ставишь им координату, так же и тут:
;1й блок
local b.blocks = New blocks
b\ent = CopyEntity(block)
;сохраняем в имени объекта "указатель на тип", который позволит
;без перебора в цикле получить доступ к объекту типа
NameEntity (b\ent, Handle(b))
PositionEntity b\ent, 0, -6, 5
;2й блок
b.blocks = New blocks
b\ent = CopyEntity(block)
NameEntity (b\ent, Handle(b))
PositionEntity b\ent, 0, -2, -15
;и так далее
для обработки коллизии игрока с блоками не нужно пробегать в цикле по блокам, т.к. можно сделать проверку коллизии не блоков с игроком, а игрока с блоками. При этом пригодятся команды Handle и Object:
Local blockEntity% = EntityCollided(player, Tblock)
If (blockEntity<>0)
;получаем "указатель на тип", который заранее сохранили в имени энтити
Local b.blocks = Object.blocks (EntityName (blockEntity))
FreeEntity (blockEntity)
Delete (b)
EndIf
а если надо по порядковому номеру (index) или идентификатору (id) получить объект из списка, то можно такие функции применить:
Function getBlockByIndex.blocks(index%)
Local b.blocks
Local i%=0
For b = Each blocks
If(i = index) Return b
i = i+1
Next
Return Null
End Function
Function getBlockById.blocks(id%)
Local b.blocks
For b = Each blocks
If(b\id = id) Return b
Next
Return Null
End Function
предварительно добавив в тип blocks поле id%.
Я рекомендую по стилю вот что:
- типы называй начиная с заглавной буквы T: TBullet, TBlock и т.д.
- типы коллизий объявляй константой и большими буквами, как сделано для пуль:
Const TYPE_PLAYER = 1
Const TYPE_BLOCK = 2
Const TYPE_BULLET = 3
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо Жека за это полезное сообщение:
|
|
05.03.2012, 12:43
|
#11
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
L-ee-X, в том-то и дело, что не так же, если поставить вместо коллизии игрока коллизию пули, то всё работает, а с игроком нет...
Жека, блоки создаются, но не более, по-всякому уже перепробовал - не получается...и ещё блитз ругается на строчку
Local b.blocks = Object.blocks (EntityName (blockEntity))
ему по ходу Local не нравится...
|
(Offline)
|
|
05.03.2012, 14:24
|
#12
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
L-ee-X, Жека, извиняюсь, я идиот, всё работает, я просто поленился разобраться как следует, спасибо за помощь
но на Local блитз всё-таки ругается
|
(Offline)
|
|
05.03.2012, 15:02
|
#13
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Сообщение от Devilox
но на Local блитз всё-таки ругается
|
радоваться надо, что ругается, т.к. он тебя пытается уберечь от присвоения в потенциально-не-ту переменную значения.
у тебя в коде выше уже есть переменная b, в той же области видимости (знаешь про такое наверное), вот и предупреждение, т.к. две одинаковые переменные нельзя объявлять, замени переменную на _b или bbb и всё окей будет.
Вообще , крайне желательно везде писать Local (и Global), и указывать типы переменных # % $.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
05.03.2012, 17:11
|
#14
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Упорядоченное исчезновение объектов
Спасибо
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:05.
|