반응형

캐릭터를 움직여 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
running = True
 
player = pygame.image.load("player.png").convert()
player.set_colorkey(player.get_at((00)))
player_size = (player.get_width()*1.5, player.get_height()*1.5)
player = pygame.transform.scale(player, player_size)
player_pos = player.get_rect()
player_pos.center = (screen.get_width()/2, screen.get_height()/2)
player_speed = 4
# 플레이어 이동 속도
player_direction = -1
# 플레이어 이동 방향
 
sound = pygame.mixer.Sound("music.mp3")
sound.play()
 
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
 
    keys = pygame.key.get_pressed()
    # 모든 키의 상태를 확인한다.
    if keys[pygame.K_LEFT]: # 왼쪽키가 눌렸다면..
        if player_direction > 0:
            player = pygame.transform.flip(player, TrueFalse)
            player_direction = -1
            # 플레이어가 오른쪽으로 이동중이었다면 왼쪽으로 반전한다.
        player_pos.move_ip(-player_speed, 0)
    if keys[pygame.K_RIGHT]: # 오른쪽키가 눌렸다면..
        if player_direction < 0:
            player = pygame.transform.flip(player, TrueFalse)
            player_direction = 1
            # 플레이어가 왼쪽으로 이동중이었다면 오른쪽으로 반전한다.
        player_pos.move_ip(player_speed, 0)
        # 플레이어를 player_speed 만큼 x축으로 이동한다.
 
    screen.fill("black")
    screen.blit(player, player_pos)
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
 

 

 

캐릭터가 좌우로 움직인다.

 

반응형
Posted by J-sean
:
반응형

사운드를 로드하고 플레이 해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
running = True
 
player = pygame.image.load("player.png").convert()
player.set_colorkey(player.get_at((00)))
player_size = (player.get_width()*1.5, player.get_height()*1.5)
player = pygame.transform.scale(player, player_size)
player_pos = player.get_rect()
player_pos.center = (screen.get_width()/2, screen.get_height()/2)
 
sound = pygame.mixer.Sound("music.mp3")
# 사운드 리소스를 로드하고 오브젝트를 반환한다.
sound.play()
# 로드한 사운드 오브젝트를 플레이한다.
 
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
 
 
    screen.fill("black")
    screen.blit(player, player_pos)
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
 

 

music.mp3
4.01MB

 

로드한 사운드가 플레이 된다.

 

반응형
Posted by J-sean
:
반응형

이미지를 로드하고 출력해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import pygame
 
pygame.init()
pygame.display.set_caption("Super fun game development")
screen = pygame.display.set_mode((640480))
clock = pygame.time.Clock()
running = True
 
player = pygame.image.load("player.png").convert()
# 플레이어 이미지를 로드하고 디스플레이와 일치하는 color format과 depth로 변환한다.
player.set_colorkey(player.get_at((00)))
# 이미지의 (0, 0) 픽셀을 colorkey로 사용한다. (0, 0) 픽셀과 같은 색상은 투명하게
# 표시된다.
player_size = (player.get_width()*1.5, player.get_height()*1.5)
player = pygame.transform.scale(player, player_size)
# 이미지를 1.5배 확대한다.
player_pos = player.get_rect()
player_pos.center = (screen.get_width()/2, screen.get_height()/2)
# 이미지의 위치를 화면 중앙으로 설정한다.
 
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
 
 
    screen.fill("black")
    screen.blit(player, player_pos)
    # 스크린에 이미지를 출력한다.
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
 

 

 

player.png

 

colorkey가 적용되어 이미지가 깔끔하게 출력된다.

 

반응형
Posted by J-sean
:
반응형

Pygame으로 게임을 개발하기 위한 기본 코드를 작성해 보자. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Example file showing a basic pygame "game loop"
# pygame 기본 셋업
import os
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'= '1'
# pygame 실행시 표시되는 메세지를 보이지 않게 한다.
# pygame을 import 하기 전에 설정해야 한다.
import pygame
 
# pygame setup
pygame.init()
pygame.display.set_caption("Super fun game development")
# 게임창 제목 표시
screen = pygame.display.set_mode((640480))
# 게임창 크기를 640X480으로 설정.
clock = pygame.time.Clock()
running = True
 
while running:
    # poll for events
    # pygame.QUIT event means the user clicked X to close your window
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False
 
    # fill the screen with a color to wipe away anything from last frame
    screen.fill("black")
 
    # RENDER YOUR GAME HERE
    pygame.draw.circle(screen, "gray", screen.get_rect().center, 100)
    # 스크린 중앙에 회색원을 하나 그린다.
 
    # flip() the display to put your work on screen
    pygame.display.flip()
 
    clock.tick(60)  # limits FPS to 60
 
pygame.quit()
 

 

 

코드를 실행하면 검은 배경에 회색 원이 하나 표시된다.

 

PYGAME_HIDE_SUPPORT_PROMPT를 설정하지 않으면 위와 같은 메세지가 표시된다.

 

반응형
Posted by J-sean
:
반응형

MAME 화면을 칵테일 모드로 바꿔보자.

 

MAME를 실행한다.

 

원하는 게임을 실행하고 TAB 키를 누른다. Video Options를 선택한다.

 

Screen #0을 선택한다.

 

Cocktail을 선택한다. 칵테일 모드가 바로 적용된다.

 

 

게임을 플레이 할 때도 계속 적용된다.

 

다른 게임도 마찬가지 방법으로 칵테일 모드를 적용할 수 있다.

 

반응형
Posted by J-sean
:

onBackPressed() deprecated

Android 2023. 8. 16. 12:02 |
반응형

Deprecated 된 onBackPressed()를 대체할 수 있는 방법을 찾아보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.example.myapplication
 
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.activity.OnBackPressedCallback
 
class MainActivity : AppCompatActivity() {
 
    private val callbackTwo = object : OnBackPressedCallback(
        true // default to enabled
    ) {
        override fun handleOnBackPressed() {
            Log.e("Sean""Back button pressed. Two.")
        }
    }
 
    private val callbackThree = object : OnBackPressedCallback(
        true // default to enabled
    ) {
        override fun handleOnBackPressed() {
            Log.e("Sean""Back button pressed. Three")
        }
    }
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 
        this.onBackPressedDispatcher.addCallback(this// LifecycleOwner
            object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                    Log.d("Sean""Back button pressed. One.")
                }
            }
        )
        this.onBackPressedDispatcher.addCallback(this// LifecycleOwner
            callbackTwo)
        this.onBackPressedDispatcher.addCallback(this// LifecycleOwner
            callbackThree)
 
        callbackThree.isEnabled = false
    }
}
 

 

소스 마지막에서 callbackThree는 disable되었다.

 

Back 버튼을 누르면 callbackTwo()가 실행된다.

 

addCallback()을 통해 여러 개의 콜백을 제공할 수 있습니다. 이렇게 하면 콜백은 추가된 순서의 역순으로 호출되며 마지막으로 추가된 콜백이 뒤로 버튼 이벤트를 처음으로 처리할 기회를 얻게 됩니다. 예를 들어, one, two 및 three라는 이름의 콜백 세 개를 순서대로 추가하면 각각 three, two 및 one의 순서로 호출됩니다.

 

콜백은 책임 연쇄(Chain of Responsibility) 패턴을 따릅니다. 체인의 각 콜백은 앞의 콜백이 사용 설정되지 않은 경우에만 호출됩니다. 즉, 앞의 예에서 콜백 two는 콜백 three가 사용 설정되지 않은 경우에만 호출됩니다. 콜백 one은 콜백 two가 사용 설정되지 않은 경우에만 호출되며 이런 방식으로 이어집니다.

 

콜백은 addCallback()을 통해 추가할 때 LifecycleOwner가 Lifecycle.State.STARTED 상태에 진입할 때까지 책임 연쇄에 추가되지 않습니다. 여러 개의 다른 중첩된 수명 주기 소유자에 등록된 콜백이 있다면 위에서 설명한 순서를 유지하는 것이 특히 중요하므로 OnBackPressedCallback의 사용 설정 상태를 변경하는 것은 일시적인 변경이 좋습니다. 그러나 OnBackPressedCallback을 전체적으로 삭제하려는 경우 remove()를 호출해야 합니다. 하지만, 콜백은 연결된 LifecycleOwner가 제거될 때 자동으로 삭제되므로 일반적으로 필수사항은 아닙니다.

 

■ onBackPressed() 활동

  • onBackPressed()를 사용하여 뒤로 버튼 이벤트를 처리하고 있다면 이 메서드 대신 OnBackPressedCallback을 사용하는 것이 좋습니다. 하지만 변경이 불가능하다면 다음 규칙이 적용됩니다.
    addCallback을 통해 등록된 모든 콜백은 super.onBackPressed()를 호출할 때 평가됩니다.
  • 안드로이드12(API Level 32) 이하 에서는 OnBackPressedCallback의 모든 등록된 인스턴스와 관계없이 onBackPressed는 항상 호출됩니다.

 

※ 참고

OnBackPressedDispatcher

Provide custom back navigation

 

반응형
Posted by J-sean
:
반응형

Deprecated 된 get() 대신 getParcelable() 사용

 

1
2
3
4
5
val requestCameraLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult())
        {
            val bitmap = it?.data?.extras?.get("dta"as Bitmap
       }
 

 

open fun get(key: String!): Any? 는 API level 33에서 Deprecated 되었다.

 

1
2
3
4
5
6
7
8
9
val requestCameraLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult())
        {
            val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                it.data?.extras?.getParcelable("data", Bitmap::class.java)
            } else {
                it?.data?.extras?.get("dta"as Bitmap
            }
       }
 

 

TIRAMISU(API level 33) 이상에서는 fun <T : Any!> getParcelable(key: String?, clazz: Class<T>): T? 를 사용하자.

 

※ 참고

getParcelable

 

반응형
Posted by J-sean
:
반응형

안드로이드 앱 프로그래밍 with 코틀린 11-6 드로어 레이아웃

 

1
2
3
4
5
6
7
8
9
10
11
<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <!-- <style name="Base.Theme.MyApplication" parent="Theme.Material3.DayNight.NoActionBar">
     액션바가 필요하다. 아래와 같이 액션바를 설정한다. -->
    <style name="Base.Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Customize your light theme here. -->
        <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
    </style>
 
    <style name="Theme.MyApplication" parent="Base.Theme.MyApplication" />
</resources>
 

 

themes.xml

 

1
2
3
4
5
<resources>
    <string name="app_name">My Application</string>
    <string name="drawer_opened">Opened</string>
    <string name="drawer_closed">Closed</string>
</resources>
 

 

strings.xml

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
 
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_horizontal|center_vertical"
            android:text="Main Activity!!" />
    </LinearLayout>
 
    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#FF0000"
        android:gravity="center_horizontal"
        android:text="I am Drawer!!"
        android:textColor="#FFFFFF"
        android:textSize="34sp" />
</androidx.drawerlayout.widget.DrawerLayout>
 

 

activity_main.xml

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.example.myapplication
 
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
 
class MainActivity : AppCompatActivity() {
    lateinit var toggle: ActionBarDrawerToggle
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
 
        toggle = ActionBarDrawerToggle(this, findViewById(R.id.drawer), R.string.drawer_opened, R.string.drawer_closed)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        toggle.syncState()
    }
 
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (toggle.onOptionsItemSelected(item)) {
            return true
        }
 
        return super.onOptionsItemSelected(item)
    }
}
 

 

MainActivity.kt

 

실행 화면

 

반응형
Posted by J-sean
: